我有一个界面:
public interface JustToCheckInterface {
@MyCheck(feature = "occurrence-logging")
void log();
void log2();
@MyCheck(feature = "check-logging")
void log3();
}
和实施:
@Component
public class JustToCheck implements JustToCheckInterface {
public void log() {
System.out.println("hello");
}
@MyCheck(feature = "check-no-logging")
public void log2() {
System.out.println("hello2");
}
public void log3() {
System.out.println("hello3");
}
}
我已经创建了注释(我的界面和spring组件中使用了注释):
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD})
@Documented
public @interface MyCheck {
@Required
String feature();
}
和顾问:
@Component
public class MyAdvisor extends AbstractPointcutAdvisor {
@Autowired
private MyMethodInterceptor myMethodInterceptor;
private final StaticMethodMatcherPointcut pointcut = new
StaticMethodMatcherPointcut() {
@Override
public boolean matches(Method method, Class<?> targetClass) {
return method.isAnnotationPresent(MyCheck.class);
}
};
@Override
public Pointcut getPointcut() {
return pointcut;
}
@Override
public Advice getAdvice() {
return myMethodInterceptor;
}
}
方法拦截器
@Component
public class MyMethodInterceptor implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
MyCheck annotation = methodInvocation.getMethod().getAnnotation(MyCheck.class);
if (mySpecialCheck(annotation.feature())) {
return methodInvocation.proceed();
}
return null;
}
}
看起来几乎可行。如果被调用的方法(覆盖父接口)具有对应的注释,则它适用于对象。但是对于在接口方法具有注释的情况下覆盖没有注释的接口的方法,它不起作用。请参阅方法log()
和log3()
。
至于我,有两个潜在的候选人可以解决:
答案 0 :(得分:2)
您可以遍历所有超类和接口&#39;查找注释的超级方法。但是您可能会找到多个注释,因为该方法可能在多个类或接口中声明。
以下是我的示例代码:
public class Q46553516 {
public static void main(String[] args) throws Exception {
// the input method
Method method = ClassB.class.getMethod("func");
// get the annotation value
Class<?> clz = method.getDeclaringClass();
List<Anno> collect = Stream.concat(
Stream.of(clz),
Stream.concat(
Stream.of(ReflectUtil.getAllSuperClasses(clz)),
Stream.of(ReflectUtil.getAllInterfaces(clz))))
.map(c -> {
try {
return c.getMethod(method.getName(), method.getParameterTypes());
} catch (Exception e) {
return null;
}
})
.filter(m -> m != null)
.map(m -> m.getAnnotation(Anno.class))
.filter(a -> a != null)
.collect(Collectors.toList());
collect.forEach(System.out::println);
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Inherited
public @interface Anno {
String value();
}
static interface Inter {
@Anno("Inter")
void func();
}
static class ClassA implements Inter {
@Override
@Anno("ClassA")
public void func() {
}
}
static class ClassB extends ClassA {
@Override
public void func() {
}
}
}
并输出:
@xdean.stackoverflow.java.reflection.Q46553516$MyCheck(feature=ClassA)
@xdean.stackoverflow.java.reflection.Q46553516$MyCheck(feature=Inter)
我使用了我的实用程序ReflectUtil
,您可以找到它here