【spring源码】六、@EnableAspectJAutoProxy

本文围绕invokeBeanFactoryPostProcessors()方法展开,该方法在refresh()方法中用于注册bean定义信息。介绍了注解@EnableAspectJAutoProxy,其作用是注册名为internalAutoProxyCreator的bean,类型为AnnotationAwareAspectJAutoProxyCreator.class,还阐述了其注册机制及相关类的继承关系和作用,提及了注册时机。

invokeBeanFactoryPostProcessors()

先说明:invokeBeanFactoryPostProcessors()是在refresh()方法中的第⑤步,他的作用是注册bean的定义信息,但还没进行创建实例。我们下面介绍了注解@EnableAspectJAutoProxy就是在这个阶段注册一个bean定义,但实例化要推迟到第⑥步registerBeanPostProcessor()完成

@EnableAspectJAutoProxy

@EnableAspectJAutoProxy的作用是给spring容器中注册一个bean:这个bean名为internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator.class “注册装配模式的切面自动代理创建器”

另外可以注意,是在invokeBeanFactoryPostProcessors()阶段进来调用注册的

@EnableAspectJAutoProxy标准在配置类上,在EnableAspectJAutoProxy接口类上有@Import(AspectJAutoProxyRegistrar.class),该@Import给容器中导入了AspectJAutoProxyRegistrar这个bean,而这个bean作用是手动注册bean定义到ac容器中。

@Target({
   
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({
   
   AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
   
   
    // 用于强制使用cglib动态代理,即使实现了接口。
    // 如果希望强制使用CGLIB代理(例如希望代理目标对象的所有方法,而不只是实现自接口的方法)// 但需要保证有CGLIB包
    boolean proxyTargetClass() default false;

    // 事务中会用到 // 是否暴露代理对象,暴露出来的代理对象和线程绑定,用的是threadLocal // 设置为true之后还得用(AopContext.currentProxy()).被调方法() 替换原来的 被调方法()
    // 比如切入点表达式是save方法,saveAll方法没在切入点表达式里,saveAll调用了save方法,此时调用saveAll方法并不执行save的AOP方法//走save的时候该轮到增强的事情已经过去了//AopContext.currentProxy()获取代理对象
    boolean exposeProxy() default false;
}

exposeProxy解释:

public interface UserService{
    
    
	public void a();
	public void a();
}

public class UserServiceImpl implements UserService{
    
    
	@Transactional(propagation = Propagation.REQUIRED)
	public void a(){
    
    
		this.b();
	}
	@Transactional(propagation = Propagation.REQUIRED_NEW)
	public void b(){
    
    
		System.out.println("b has been called");
	}
}
代码参照《Spring源码解析》p173页。
Q1:b中的事务会不会生效?
A1:不会,a的事务会生效,b中不会有事务,因为a中调用b属于内部调用,没有通过代理,所以不会有事务产生。
Q2:如果想要b中有事务存在,要如何做?
A2:<aop:aspectj-autoproxy expose-proxy=true> ,设置expose-proxy属性为true,将代理暴露出来,使用AopContext.currentProxy()获取当前代理,将this.b()改为((UserService)AopContext.currentProxy()).b
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值