使用AopContxt.currentProxy()方法可获取当前类的代理对象(是通过StaticUnadvisedExposedInterceptor或DynamicUnadvisedExposedInterceptor或JdkDynamicAopProxy#invoke中设置的,@EnableAspectJAutoProxy#exposeProxy可设置为true,将当前的aop对象暴露到AopContext的ThreadLocal变量currentProxy中)
在周宁等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供成都网站设计、做网站 网站设计制作专业公司,公司网站建设,企业网站建设,品牌网站设计,全网整合营销推广,成都外贸网站制作,周宁网站建设费用合理。在使用@Transactional注解声明事务时,会有以下四种情况:
在不同类中,事务方法A调用非事务方法B,事务具有传播性,事务生效;
在不同类中,非事务方法A调用事务方法B,事务生效;
在同一个类中,事务方法A调用非事务方法B,事务生效;
在同一个类中,非事务方法A调用事务方法B,事务失效,这是由于使用Spring AOP代理造成的,只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
解决办法:
- 采用AopContext.currentProxy().方法B名()来进行调用
- ApplicationContext.getBean()
- 在当前类中注入自己
- 使用手动事务
如果该类存在@Async异步任务方法,那么@Async方法应该使用第3种方式并且在引入的自身代理对象上加上@Lazy注解,让其再进行代理封装(看这里: Spring AOP入门以及基于XML的Spring AOP配置的深入学习与使用【两万字】_刘Java的博客-博客)
思考:为什么在被代理类的方法中调用被代理的其它方法时,不经过增强方法呢?
这是由aop的实现机制决定的,spring aop抽象出了TargetSource接口(从中可以获取target目标对象),当外部通过调用代理对象的方法时,就会经过MethodInterceptor方法拦截器(增强方法),当所有的方法拦截器都调用完了(责任链模式),就会从代理配置(ProxyFactory->ProxyCreatorSupport->AdvisedSupport中维护targetSource)的TargetSource中获取到目标对象,然后使用反射调用该目标对象的目标方法,也就是最终目标对象执行时,其实这个时候已经不是代理对象了,此时是目标对象!那么反射方法执行时,方法中的this,就是目标对象,那在一个成员方法中调用类中的另外一个成员方法(此时省略了this),省略的这个this是目标对象,而不是代理对象,因此被调用的另外一个成员方法时,是不会经过增强方法的(方法拦截器)。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网站题目:AopContxt.currentProxy()-创新互联
标题链接:http://lswzjz.com/article/dhddcs.html