java8可重复注解+反射

Posted master-dragon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java8可重复注解+反射相关的知识,希望对你有一定的参考价值。

不可重复注解

  • IUser
public interface IUser {
    void call();

    void say();
}
  • IUser的实现类
public class Teacher implements IUser {

    @AccessContainer({@Access(AccessEnum.A)})
    @Override
    public void call() {
        System.out.println("call success");
    }

    @AccessContainer({@Access(AccessEnum.A), @Access(AccessEnum.B)})
    @Override
    public void say() {
        System.out.println("say success");
    }

}
  • 注解类
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Access {
    AccessEnum value();
}

注解数组

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessContainer {
    Access[] value();
}
public enum AccessEnum {
    A("A"),
    B("B");

    String right;

    AccessEnum(String right) {
        this.right = right;
    }

    public String getRight() {
        return right;
    }

    public void setRight(String right) {
        this.right = right;
    }

}
  • 代理类
public class UserClass {
    public static IUser getDynamicProxy(IUser iUser) {
        UserProxy userProxy = new UserProxy(iUser);
        return (IUser) Proxy.newProxyInstance(IUser.class.getClassLoader(), new Class<?>[]{IUser.class}, userProxy);
    }
}

判断方法实现上有特定注解才能正常执行

public class UserProxy implements InvocationHandler {

    private IUser target;

    public UserProxy(IUser iPeople){
        this.target = iPeople;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean hasRight = false;
        Method targetMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes());
        AccessContainer accessContainer = targetMethod.getAnnotation(AccessContainer.class);
        if (accessContainer != null) {
            Access[] accesses = accessContainer.value();
            for (Access access : accesses) {
                if (access.value() == AccessEnum.A) {
                    hasRight = true;
                    break;
                }
            }
        }
        if (hasRight) {
            Object result = method.invoke(target, args);
            return result;
        }
        System.out.println(target.getClass().getSimpleName() + " has no right for method:" + method);
        return null;
    }
}

测试

可重复注解

当一个注解不是可重复注解的时候,如下使用会飘红

声明一个可重复注解

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(RepeatableAccesss.class) //可重复注解,RepeatableAccesss存储RepeatableAccess
public @interface RepeatableAccess {
    AccessEnum value();
}
@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RepeatableAccesss {
    RepeatableAccess[] value();
}

使用可重复注解

可以重复注解,而不会飘红

public class Worker implements IUser {

    @RepeatableAccess(AccessEnum.A)
    @RepeatableAccess(AccessEnum.B)
    @Override
    public void call() {
        System.out.println("call success");
    }

    @Override
    public void say() {
        System.out.println("say success");
    }

}
  • 代理
public class RepeatableUserClass {
    public static IUser getDynamicProxy(IUser iUser){
        RepeatableUserProxy userProxy = new RepeatableUserProxy(iUser);
        return (IUser) Proxy.newProxyInstance(IUser.class.getClassLoader(), new Class<?>[]{IUser.class}, userProxy);
    }
}
public class RepeatableUserProxy implements InvocationHandler {

    private IUser target;

    public RepeatableUserProxy(IUser iPeople){
        this.target = iPeople;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        boolean hasRight = false;
        Method targetMethod = target.getClass().getMethod(method.getName(), method.getParameterTypes());
        RepeatableAccess[] repeatableAccesses = targetMethod.getDeclaredAnnotationsByType(RepeatableAccess.class);
        if (repeatableAccesses != null) {
            for (RepeatableAccess access : repeatableAccesses) {
                if (access.value() == AccessEnum.A) {
                    hasRight = true;
                    break;
                }
            }
        }
        if (hasRight) {
            Object result = method.invoke(target, args);
            return result;
        }
        System.out.println(target.getClass().getSimpleName() + " has no right for method:" + method);
        return null;
    }
}

测试

测试如下:

以上是关于java8可重复注解+反射的主要内容,如果未能解决你的问题,请参考以下文章

利用注解 + 反射消除重复代码,妙!

利用注解 + 反射消除重复代码,牛逼!

利用注解 + 反射消除重复代码,妙!

利用注解 + 反射消除重复代码,妙!

利用注解 + 反射消除重复代码,妙!

Java 8,流过滤器,反射,NoSuchMethodException [重复]