您的位置:首页 > 编程语言 > Java开发

【spring源码学习】spring的aop目标对象中进行自我调用,且需要实施相应的事务定义的解决方案

2017-10-12 15:22 966 查看

转载:http://www.iteye.com/topic/1122740

1、预备知识

aop概念请参考【http://www.iteye.com/topic/1122401】和【http://jinnianshilongnian.iteye.com/blog/1418596

spring的事务管理,请参考【http://jinnianshilongnian.iteye.com/blog/1441271

使用AOP 代理后的方法调用执行流程,如图所示

@Component
public class InjectBeanSelfProcessor2 implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext context;
//① 注入ApplicationContext
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.context = applicationContext;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if(!(bean instanceof BeanSelfAware)) { //② 如果Bean没有实现BeanSelfAware标识接口 跳过
return bean;
}
if(AopUtils.isAopProxy(bean)) { //③ 如果当前对象是AOP代理对象,直接注入
((BeanSelfAware) bean).setSelf(bean);
} else {
//④ 如果当前对象不是AOP代理,则通过context.getBean(beanName)获取代理对象并注入
//此种方式不适合解决prototype Bean的代理对象注入
((BeanSelfAware)bean).setSelf(context.getBean(beanName));
}
return bean;
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}


View Code

5、总结

纵观其上:

【3.1 通过ThreadLocal暴露Aop代理对象】适合解决所有场景(不管是singleton Bean还是prototype Bean)的AOP代理获取问题(即能解决目标对象的自我调用问题);

【3.2 通过初始化方法在目标对象中注入代理对象】 和【3.4 改进版的InjectBeanSelfProcessor的解决方案】能解决普通(无循环依赖)的AOP代理对象注入问题,而且也能解决【3.3】中提到的循环依赖(应该是singleton之间的循环依赖)造成的目标对象无法注入AOP代理对象问题,但该解决方案不适合解决循环依赖中包含prototype Bean的自我调用问题;

【3.3 通过BeanPostProcessor 在目标对象中注入代理对象】:只能解决 普通(无循环依赖)的 的Bean注入AOP代理,无法解决循环依赖的AOP代理对象注入问题,即无法解决目标对象的自我调用问题。

jingnianshilongnian 写道

spring允许的循环依赖(只考虑单例和原型Bean):
A----B
B----A
只有在A和B都不为原型是允许的,即如果A和B都是prototype则会报错(无法进行原型Bean的循环依赖)。
A(单例)---B(单例) 或 A(原型)---B(单例) 这是可以的,但 A(原型)---B(原型)或 A(原型)---B(单例Lazy)【且context.getBean("A")】时 这是不允许的。

一、A(原型)---B(原型) A(原型)---B(单例Lazy)【且context.getBean("A")】 会报:
Error
creating bean with name 'BServiceImpl': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.sishuok.issue.AService
com.sishuok.issue.impl.BServiceImpl.aService; nested exception is
org.springframework.beans.factory.BeanCreationException: Error creating
bean with name 'AServiceImpl': Injection of autowired dependencies
failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private com.sishuok.issue.BService
com.sishuok.issue.impl.AServiceImpl.bService; nested exception is
org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'BServiceImpl': Requested bean is
currently in creation: [color=red]Is there an unresolvable circular
reference[/color]?

二、A(原型)---B(单例) 和 A(单例)---B(单例)
这种方式 使用我的 【3.3 通过BeanPostProcessor 在目标对象中注入代理对象】 是没有问题的。

因此【
3.4 改进版的InjectBeanSelfProcessor的解决方案 】 可以作为最后的解决方案。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: