对于具有特定注释的类的所有方法,@AspectJ切点

我想用指定的注释(比如@Monitor)来监视所有类的所有公共方法(注意:注解是在类级别的)。 这可能是一个可能的切入点? 注意:我正在使用@AspectJ风格的Spring AOP。

你应该把一个types切入点和一个方法切入点结合起来。

这些切入点将完成查找标有@Monitor注解的类中的所有公共方法的工作:

@Pointcut("within(@org.rejeev.Monitor *)") public void beanAnnotatedWithMonitor() {} @Pointcut("execution(public * *(..))") public void publicMethod() {} @Pointcut("publicMethod() && beanAnnotatedWithMonitor()") public void publicMethodInsideAClassMarkedWithAtMonitor() {} 

build议最后的切入点,结合前两个,你就完成了!

如果你有兴趣,我在这里写了一个@AspectJ风格的备忘单 ,在这里有一个相应的示例文档 。

使用注释,如问题中所述。

注释: @Monitor

class, app/PagesController.java

 package app; @Controller @Monitor public class PagesController { @RequestMapping(value = "/", method = RequestMethod.GET) public @ResponseBody String home() { return "w00t!"; } } 

方法的注释, app/PagesController.java

 package app; @Controller public class PagesController { @Monitor @RequestMapping(value = "/", method = RequestMethod.GET) public @ResponseBody String home() { return "w00t!"; } } 

自定义注释, app/Monitor.java

 package app; @Component @Target(value = {ElementType.METHOD, ElementType.TYPE}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Monitor { } 

注释方面, app/MonitorAspect.java

 package app; @Component @Aspect public class MonitorAspect { @Before(value = "@within(app.Monitor) || @annotation(app.Monitor)") public void before(JoinPoint joinPoint) throws Throwable { LogFactory.getLog(MonitorAspect.class).info("monitor.before, class: " + joinPoint.getSignature().getDeclaringType().getSimpleName() + ", method: " + joinPoint.getSignature().getName()); } @After(value = "@within(app.Monitor) || @annotation(app.Monitor)") public void after(JoinPoint joinPoint) throws Throwable { LogFactory.getLog(MonitorAspect.class).info("monitor.after, class: " + joinPoint.getSignature().getDeclaringType().getSimpleName() + ", method: " + joinPoint.getSignature().getName()); } } 

启用AspectJ, servlet-context.xml

 <aop:aspectj-autoproxy /> 

包含AspectJ库, pom.xml

 <artifactId>spring-aop</artifactId> <artifactId>aspectjrt</artifactId> <artifactId>aspectjweaver</artifactId> <artifactId>cglib</artifactId> 

类似的东西:

 @Before("execution(* com.yourpackage..*.*(..))") public void monitor(JoinPoint jp) { if (jp.getTarget().getClass().isAnnotationPresent(Monitor.class)) { // perform the monitoring actions } } 

请注意, 之前 ,您不能在同一个类别上提供任何其他build议,因为注释在代理之后将会丢失。

你也可以定义切入点

 public pointcut publicMethodInsideAClassMarkedWithAtMonitor() : execution(public * (@Monitor *).*(..)); 

这应该足以标记你的方面的方法是这样的:

 @After("@annotation(com.marcot.CommitTransaction)") public void after() { 

看看这个一步一步的指导。

最简单的方法似乎是:

 @Around("execution(@MyHandling * com.exemple.YourService.*(..))") public Object aroundServiceMethodAdvice(final ProceedingJoinPoint pjp) throws Throwable { // perform actions before return pjp.proceed(); // perform actions after } 

它将拦截“YourService”类中的所有使用“@MyHandling”注解的方法的执行。 要毫无例外地拦截所有方法,只需将注释直接放在类上即可。

不pipe这里的私有/公共范围如何,但请记住,spring-aop不能在同一个实例中使用方面调用(通常是私有方法),因为在这种情况下它不使用代理类。

我们在这里使用了@Around的build议,但是它和@Before,@After或者任何build议基本上是一样的。

顺便说一句,@MyHandling注释必须像这样configuration:

 @Retention(RetentionPolicy.RUNTIME) @Target( { ElementType.METHOD, ElementType.TYPE }) public @interface MyHandling { } 

从“spring的AnnotationTransactionAspect

 /** * Matches the execution of any public method in a type with the Transactional * annotation, or any subtype of a type with the Transactional annotation. */ private pointcut executionOfAnyPublicMethodInAtTransactionalType() : execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *); 

您可以使用Spring的PerformanceMonitoringInterceptor并以编程方式注册使用beanpost处理器的build议。

 @Target({ ElementType.TYPE, ElementType.METHOD }) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented public @interface Monitorable { } public class PerformanceMonitorBeanPostProcessor extends ProxyConfig implements BeanPostProcessor, BeanClassLoaderAware, Ordered, InitializingBean { private Class<? extends Annotation> annotationType = Monitorable.class; private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); private Advisor advisor; public void setBeanClassLoader(ClassLoader classLoader) { this.beanClassLoader = classLoader; } public int getOrder() { return LOWEST_PRECEDENCE; } public void afterPropertiesSet() { Pointcut pointcut = new AnnotationMatchingPointcut(this.annotationType, true); Advice advice = getInterceptor(); this.advisor = new DefaultPointcutAdvisor(pointcut, advice); } private Advice getInterceptor() { return new PerformanceMonitoringInterceptor(); } public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) { if(bean instanceof AopInfrastructureBean) { return bean; } Class<?> targetClass = AopUtils.getTargetClass(bean); if(AopUtils.canApply(this.advisor, targetClass)) { if(bean instanceof Advised) { ((Advised)bean).addAdvisor(this.advisor); return bean; } else { ProxyFactory proxyFactory = new ProxyFactory(bean); proxyFactory.copyFrom(this); proxyFactory.addAdvisor(this.advisor); return proxyFactory.getProxy(this.beanClassLoader); } } else { return bean; } } } 

使用

 @Before("execution(* (@YourAnnotationAtClassLevel *).*(..))") public void beforeYourAnnotation(JoinPoint proceedingJoinPoint) throws Throwable { }