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可重复注解+反射的主要内容,如果未能解决你的问题,请参考以下文章