example - Java Spring AOP: uso de CustomTrakeInterceptor con JavaConfig @EnableAspectJAutoProxy, no XML<aop: consejero>
spring boot aop example (3)
Spring AOP tiene un rastreador de nivel de método llamado CustomizableTraceInterceptor
. Utilizando el enfoque de configuración XML de Spring, uno configuraría este rastreador de la siguiente manera:
<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>
Me gustaría configurar la configuración anterior utilizando el estilo JavaConfig de Spring (es decir, aprovechar las anotaciones de Java, especialmente @EnableAspectJAutoProxy
para activar AspectJ en JavaConfig).
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = { "some.package" })
@ComponentScan(basePackages = { "some.package2", "some.package3" })
@EnableAspectJAutoProxy
public class FacebookDomainConfiguration {
@Bean someBean() {
...
}
...
}
¿Cuál es el equivalente del estilo @EnableAspectJAutoProxy
para <aop:advisor advice-ref="customizableTraceInterceptor" ...>
?
Lamentablemente, no se puede porque el lenguaje Java no es compatible con los literales de métodos que se necesitarían para admitir esto en Spring JavaConfig. Se abrió un error para esto pero marcado como "No se Corrige": https://jira.springsource.org/browse/SPR-8148 .
Las dos opciones mencionadas en el informe de error son:
- Continúe usando
<aop:config>
incluyendo el fragmento XML relevante con@ImportResource
- Convierta cualquier elemento
<aop:config>
existente para usar el estilo@Aspect
. [que no es posible con elCustomizableTraceInterceptor
]
Lo hago de esta manera:
@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());
}
}
Solo quería agregar a la respuesta de AdrienC. Usaré la expresión de puntos para hacer referencia a un punto agregado, una separación más clara,
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());
}
}