【问题标题】:AspectJ, SpringAOP, Aspect runs twiceAspectJ、SpringAOP、Aspect 运行两次
【发布时间】:2018-05-17 09:23:03
【问题描述】:

我的方面运行了两次,但我看不出原因。也许有人可以指出我的错误? 这是一个代码:

  1. 为切入点创建注释

    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.METHOD})
    public @interface CustodianMetrics {
        String metricId();
    }
    
  2. 创建一个方面

    @Aspect
    @Component("custodianMetricsAspect")
    public class CustodianMetricsAspect {
        private final MonitoringService monitoringService;
    
        @Autowired
        public CustodianMetricsAspect(MonitoringService monitoringService) {
            this.monitoringService = monitoringService;
        }
    
        @After("@annotation(custodianMetricsAnnotation)")
        public void count(CustodianMetrics custodianMetricsAnnotation) {
            Counter metric = monitoringService.metric(custodianMetricsAnnotation.metricId(), Counter.class);
            metric.inc();
        }
    }
    
  3. 为spring配置xml

    <aop:aspectj-autoproxy>
        <aop:include name="path"/>
    </aop:aspectj-autoproxy>
    <aop:config>
        <aop:aspect id="custodianMetricsAspect" ref="custodianMetricsAspect">
            <aop:after method="count" 
                     pointcut="@annotation(custodianMetricsAnnotation)"/>
        </aop:aspect>
    </aop:config>
    

我试图改变这个位置

@After("@annotation(custodianMetricsAnnotation) && execution(* *(..))")

但结果相同 - 方面运行两次。有什么建议吗?

【问题讨论】:

  • 作为一个可能不相关的建议,您应该将切入点限制在包级别,即execution(public * org.mypackage..*.*(..))
  • 如果您的@Component 方面的组件扫描处于活动状态,@Nikolas 的回答可能是正确的。但只是为了确保它确实是两次触发的同一个连接点,而不是另一个类因为它也带有相同的注释而被意外拦截,您可以将 JoinPoint thisJoinPoint 作为第一个参数添加到您的 count() 建议中,然后将其打印到像System.out.println(thisJoinPoint) 这样的控制台。那你就真的知道了。

标签: java spring aspectj spring-aop


【解决方案1】:

这是因为您已经配置了方面两次 - Spring XML 配置和 @Aspect 注释。

阅读 Spring 框架文档8.1.2 Spring AOP capabilities and goals 部分的注释,它声明如下:

与本章相关的一个选择是选择哪种 AOP 框架(以及哪种 AOP 风格)。您可以选择 AspectJ 和/或 Spring AOP,还可以选择 @AspectJ 注释样式方法或 Spring XML 配置样式方法。

在这种情况下,根据我的个人经验,我强烈建议您坚持使用注释。但是,这取决于您的个人品味。您可能会发现 8.4 Choosing which AOP declaration style to use 相关。

编辑: 如果选择基于注解的配置,别忘了创建一个Java配置类,而不是删除&lt;aop:aspectj-autoproxy&gt;...这一行。

@Configuration
@EnableAspectJAutoProxy
public class AspectJAutoProxyConfiguration { }

【讨论】:

  • &lt;aop:aspectj-autoproxy&gt; &lt;aop:include name="path"/&gt; &lt;/aop:aspectj-autoproxy&gt; 文我用这个配置方面根本没有运行
  • 你需要一个用@Configuration @EnableAspectJAutoProxy注解的Java配置(空)类。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多