Java Spring AOP: 使用可自定义的TraceInterceptor 和 JavaConfig 的 @EnableAspectJAutoProxy,而不是 XML <aop:advisor>。

20

Spring AOP拥有一个名为CustomizableTraceInterceptor的方法级跟踪器。使用Spring的XML配置方法,可以像这样设置该跟踪器:

Spring AOP还有一种基于注解的跟踪器,称为@Traced,可以通过在方法上添加注解来启用跟踪。

<bean id="customizableTraceInterceptor" class="
  org.springframework.aop.interceptor.CustomizableTraceInterceptor">
  <property name="enterMessage" value="Entering $[methodName]($[arguments])"/>
  <property name="exitMessage" value="Leaving $[methodName](): $[returnValue]"/>
</bean>

<aop:config>
  <aop:advisor advice-ref="customizableTraceInterceptor"
    pointcut="execution(public * org.springframework.data.jpa.repository.JpaRepository+.*(..))"/>
</aop:config>

我希望使用Spring的JavaConfig样式来设置上述配置(即利用Java注释,特别是@EnableAspectJAutoProxy来激活JavaConfig中的AspectJ)。

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "some.package" })
@ComponentScan(basePackages = { "some.package2", "some.package3" })
@EnableAspectJAutoProxy
public class FacebookDomainConfiguration {

    @Bean someBean() {
    ...
    }
...
}

<aop:aspectj-autoproxy/>@EnableAspectJAutoProxy风格的等效替代品,用于<aop:advisor advice-ref="customizableTraceInterceptor" ...>

3个回答

29

我是这样做的:

@Configuration
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class TraceLoggerConfig {

    @Bean
    public CustomizableTraceInterceptor customizableTraceInterceptor() {
        CustomizableTraceInterceptor customizableTraceInterceptor = new CustomizableTraceInterceptor();
        customizableTraceInterceptor.setUseDynamicLogger(true);
        customizableTraceInterceptor.setEnterMessage("Entering $[methodName]($[arguments])");
        customizableTraceInterceptor.setExitMessage("Leaving  $[methodName](), returned $[returnValue]");
        return customizableTraceInterceptor;
    }

    @Bean
    public Advisor jpaRepositoryAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("execution(public * org.springframework.data.jpa.repository.JpaRepository+.*(..))");
        return new DefaultPointcutAdvisor(pointcut, customizableTraceInterceptor());
    }

}

3
谢谢!这应该被接受为正确答案。 - AndiDev
2
我使用了上面的代码,但是 CustomizableTraceInterceptor 似乎没有被触发。 - Guisong He

17

我只是想补充一下AdrienC的回答。 我将使用点号表示法来引用聚合的点,这样更清晰地分离,个人认为。

package org.example;

@Configuration
@EnableAspectJAutoProxy
@Aspect
public class AopConfiguration {
    /** Pointcut for execution of methods on {@link Service} annotation */
    @Pointcut("execution(public * (@org.springframework.stereotype.Service org.example..*).*(..))")
    public void serviceAnnotation() { }

    /** Pointcut for execution of methods on {@link Repository} annotation */
    @Pointcut("execution(public * (@org.springframework.stereotype.Repository org.example..*).*(..))")
    public void repositoryAnnotation() {}

    /** Pointcut for execution of methods on {@link JpaRepository} interfaces */
    @Pointcut("execution(public * org.springframework.data.jpa.repository.JpaRepository+.*(..))")
    public void jpaRepository() {}

    @Pointcut("serviceAnnotation() || repositoryAnnotation() || jpaRepository()")
    public void performanceMonitor() {}

    @Bean
    public PerformanceMonitorInterceptor performanceMonitorInterceptor() {
        return new PerformanceMonitorInterceptor(true);
    }

    @Bean
    public Advisor performanceMonitorAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("org.example.AopConfiguration.performanceMonitor()");
        return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor());
    }
}

2
在我看来,这应该被标记为正确答案,我刚刚验证了一下 Spring 4。 :) - Andrew Landsverk
谢谢你!我从早上开始就一直在寻找这个解决方案!)) - Dante

4
很抱歉,由于Java语言不支持方法文字,因此无法在Spring JavaConfig中支持此功能。已为此问题打开了一个错误报告,但被标记为“不会修复”:https://jira.springsource.org/browse/SPR-8148
错误报告中提到的两个选项如下:
  1. 继续使用 <aop:config>,通过使用 @ImportResource 导入相关的XML片段。
  2. 将现有的 <aop:config> 元素转换为使用 @Aspect 样式。 [不可能使用CustomizableTraceInterceptor]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接