使用spring事务时,需要调用自身的其他方法,通常使用自注入解决问题。这种方式处理起来简单方便,如果自注入后再要用这个bean中普通方法再调用注入的bean,会报空指针异常!
@Autowired field方式注入,属性注入
@Resource 和 @Autowired的区别:
- 都是用来自动装配的,都放在属性字段上
- @Autowired 通过byType的方式实现,而且必须要求这个对象存在!【常用】
- @Resource 默认通过byname的方式实现,如果找不到名字,则通过byType实现!如果两个都找不到的情况下,就报错!【常用】
- 执行顺序不同:@Autowired 通过byType的方式实现。@Resource 默认通过byname的方式实现。
构造注入,无法解决循环依赖问题!<=== Bean实例化失败,无法进入第二步填充属性。
构造函数注入,可以提前更早的发现循环依赖!
// setter方式注入
// 1.定义成员变量
private MyBean myBean;
// 2.setter 注入
@Autowired
public void setMyBean(MyBean myBean) {
this.myBean = myBean;
}
循环问题解决时机
spring解决单例模式下循环依赖
A.class与B.class相互依赖,形成循环依赖
1. A实例化自己的时候发现自己依赖B,会先将自己放入三级缓存,先去实例化B
2.B实例化的时候发现发现自己依赖A,先去查一级缓存,没有,接着去二级缓存查,还没有,再去查三级缓存,找到。然后将三级缓存中的A放入二级缓存,并删掉三级缓存中的A。此时B完成自己的实例化。然后把自己放入一级缓存中,同时删除二级缓存中的自己。
3.再去实例化A,A再去查一级缓存,完成自己的实例化,然后把自己放入一级缓存中,同时删除三级缓存中的自己。
4.完成1、2、3后完成各自的实例化。
循环依赖,原型模式会怎样?
Bean加上注解 @Scope(BeanDefinition.SCOPE_PROTOTYPE)
无法提前暴露,因为每次都new新的Bean!!!
@SpringBootApplication
@Import({ServiceA.class, ConfigurationA.class, BeanB.class})
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
@Import
扫描Bean是为了方便指定Bean的初始化顺序。Spring会按照@Import
的顺序依次加载Bean。同时,在加载每个Bean的时候,如果这个Bean有需要注入的依赖,则会试图加载他依赖的Bean。
先加载BeanA
- 当Spring在试图加载ServiceA时,先构造了ServiceA,然后发现他依赖BeanA,于是就试图去加载BeanA;
- Spring想构造BeanA,但是发现BeanA在ConfigurationA内部,于是又试图加载ConfigurationA(此时BeanA仍未构造);
- Spring构造了ConfigurationA的实例,然后发现他依赖BeanB,于是就试图去加载BeanB。
- Spring构造了BeanB的实例,然后发现他依赖BeanA,于是就试图去加载BeanA。
- Spring发现BeanA还没有实例化,此时Spring发现自己回到了步骤2。。。GG。。。
先加载BeanB
- 当Spring在试图加载ServiceA时,先构造了ServiceA,然后发现他依赖BeanB,于是就试图去加载BeanB;
- Spring构造了BeanB的实例,然后发现他依赖BeanA,于是就试图去加载BeanA。
- Spring发现BeanA在ConfigurationA内部,于是试图加载ConfigurationA(此时BeanA仍未构造);
- Spring构造了ConfigurationA的实例,然后发现他依赖BeanB,并且BeanB的实例已经有了,于是将这个依赖填充进ConfigurationA中。
- Spring发现ConfigurationA已经完成了构造、填充了依赖,于是想起来构造了BeanA。
- Spring发现BeanA已经有了实例,于是将他给了BeanB,BeanB填充的依赖完成。
- Spring回到了为ServiceA填充依赖的过程,发现还依赖BeanA,于是将BeanA填充给了ServiceA。
- Spring成功完成了初始化操作。
再来看,自己注入自己,然后再使用自己注入自己的这个代理类,普通方法未被代理。。。
自注入后异步也会出问题!