我想使用自定义注释对带注释的类的所有方法执行简单的日志。我创建了下一个注释:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface FooAnnotation {}
它用于随机类:
@FooAnnotation
public class Bar{
...
}
当然我的起始类有@EnableAspectJAutoProxy注释
@EnableAspectJAutoProxy
@SpringBootApplication
public class FooApplication {
public static void main(String[] args) {
SpringApplication.run(FooApplication.class, args);
}
}
在相关的AspectJ中,我需要定义一个@Pointcut来对所有用@FooAnnotation注释的类的所有方法执行@After>
我尝试了下一个 AspectJ,但它不起作用
@Slf4j
@Aspect
@Component
public class FooAspectJ{
@Pointcut("within(x.y.z.FooNotify)")
private void annotatedWithin() {}
@Pointcut("@within(x.y.z.FooNotify)")
private void annotatedAtWithin() {}
@Pointcut("@annotation(x.y.z.FooNotify)")
private void annotatedAtAnnotation() {}
@After("annotatedWithin() || annotatedAtWithin() || annotatedAtAnnotation()")
private void afterAnnotation(JoinPoint joinPoint){
log.info("Executed annotated {}", joinPoint.getSignature().getName());
}
}
我看到类似的帖子,比如 @AspectJ pointcut for all methods of a class with specific annotation和 aspectj pointcut with annotation parameters ,结果相同。
最佳答案
应该是这样的
@Pointcut("within(@x.y.z.FooNotify *)")
示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
@FooNotify
@Repository
public class Bar {
private static final Logger logger = LoggerFactory.getLogger(Bar.class);
public String returnSomeString() {
logger.info("returnSomeString ...");
int i = returnMeAnInt();
logger.info("returnMeAnInt returned {}", i);
return "Hello";
}
public void doSomething() {
logger.info("doSomething ...");
}
private int returnMeAnInt() {
logger.info("returnMeAnInt ...");
return 4;
}
}
方面:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class BarAspect {
private static final Logger logger = LoggerFactory.getLogger(BarAspect.class);
@Pointcut("within(@FooNotify *)")
public void fooNotifyPointcut() {}
@After("fooNotifyPointcut()")
public void afterAnnotation(JoinPoint jp) {
logger.info("afterAnnotation joinpoint: {}", jp.getStaticPart().getSignature());
}
}
注释:
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(TYPE)
public @interface FooNotify {}
通话:
bar.returnSomeString();
bar.doSomething();
日志:
Bar:13- returnSomeString ...
Bar:24- returnMeAnInt ...
Bar:15- returnMeAnInt returned 4
BarAspect:21- afterAnnotation joinpoint: String com.pkg.Bar.returnSomeString()
Bar:20- doSomething ...
BarAspect:21- afterAnnotation joinpoint: void com.pkg.Bar.doSomething()
对于私有(private)方法,您必须使用完整的aspectj。
关于java - 使用 Target=ElementType.TYPE 创建 AspectJ 进行注释(类注释),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58933756/