@EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
// 是否代理目标对象,ture:使用CGLIB代理 fasle:使用JDK代理
boolean proxyTargetClass() default false;
// 是否暴露代理对象
boolean exposeProxy() default false;
}
@EnableAspectJAutoProxy
是一个Spring框架的注解,用于启用基于AspectJ的代理支持。它允许您使用面向切面编程 (AOP) 来实现横切关注点,例如日志记录、性能监控、事务管理等。
具体来说,@EnableAspectJAutoProxy
做了以下几件事情:
1、启用代理机制:它启用了Spring容器的代理功能,允许Spring创建代理对象,以拦截和处理方法调用,正常来说是不需要主动去加该注解,因为由于SpringBoot的自动配置会将代理机制自动开启。截取源代码中的注释。
package org.springframework.boot.autoconfigure.aop;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} for Spring's AOP support. Equivalent to enabling
* {@link EnableAspectJAutoProxy @EnableAspectJAutoProxy} in your configuration.
* <p>
* The configuration will not be activated if {@literal spring.aop.auto=false}. The
* {@literal proxyTargetClass} attribute will be {@literal true}, by default, but can be
* overridden by specifying {@literal spring.aop.proxy-target-class=false}.
*
* 大致意思就是:
* 可以使用@EnableAspectJAutoProxy启用AOP的相关能力。
* 如果要关闭AOP的能力可以配置「spring.aop.auto=false」,另外注解中的「proxyTargetClass」
* 属性默认为true,代表使用CGLIB代理,「SpringBoot 2.0以后默认」;也可自行配置使用
*「spring.aop.proxy-target-class=false」使用JDK代理,或者「proxyTargetClass=false」
* @author Dave Syer
* @author Josh Long
* @since 1.0.0
* @see EnableAspectJAutoProxy
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(Advice.class)
static class AspectJAutoProxyingConfiguration {
.....
2、使用AspectJ注解:它启用了AspectJ注解,使您可以在Spring中使用 @Aspect
、@Before
、@After
、@Around
等注解来定义切面。
3、配置代理模式:它允许您选择代理的模式,通常是 proxyTargetClass
和 exposeProxy
选项。proxyTargetClass
默认为 false
,表示使用标准的JDK动态代理,如果将其设置为 true
,则使用CGLIB代理。exposeProxy
默认为 false
,表示不将当前代理对象暴露给切面,如果将其设置为 true
,可以通过 AopContext.currentProxy()
获取当前代理对象。
以下是一个示例:
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class AppConfig {
// Other bean configurations can go here
}
典型应用:
1、解决由于代理实现的机制的失效问题:
比如@Transactional事务、@Async异步,Service内部方法自调用导致的失效
// 配置暴露代理类,通过获取代理类调取方法
((TUserService) AopContext.currentProxy()).updateRealNameById(id, realName);