bean的生命周期是怎样的?
UserService—>推断构造方法①—>普通对象---->依赖注入(1.找属性2.给属性赋值)—>初始化前(@PostConstruct)---->初始化(InitiallizingBean)---->初始化后(AOP)---->代理对象②---->如果需要单例bean放到单例池(一级缓存)---->Bean对象
① 对于spring 一个类里面有多个构造方法,他会优先在这里面使用无参构造方法,如果没找到的话,那么它将报错!!
但是我们可以自己指定用哪个构造方法,用@Autowired
这样我们指定的构造方法,对于参数来说会现根据byType 从容器中进行查找,如果找到了一个,那么就使用这个,不用再根据byName;但如果找到了多个,那么就根据byName进行查找。byType–>byName
如果@Autowired 修饰的是属性,那么跟修饰构造方法差不多,唯一的区别是如果根据byType–>byName 找不到的话,那么就会自己创建一个bean.
② cglib
此时我们得到的是一个UserService 的代理类对象,但是代理类对象没有依赖注入这个环节,所以此时的属性orderService 为null。
但是进到test()方法之后,orderService 的值不为null了。
关于spring事务
在a方法上面再加一个注解,此时失效因为a方法的调用对象为原始对象,只有代理对象调用才管用。
解决方法:
①在建一个类UserServiceBase 里面有带注解的a()方法
②UserService 对象自己调用自己
循环依赖以及三级缓存
三级缓存
一级缓存:singletonObjects Map<beanName, Object>(单例池)
二级缓存:earlySingtonObjects Map<beanName, Object> 保证单例
三级缓存: singletonFactories Map<beanName, lamda表达式> 用于拿到AOP 要产生的代理对象的原始对象
AService 与BService 构成循环依赖
AService 出现循环依赖的情况下,提前进行AOP
0、creatingSet.add(aService).
1、class–> 实例化得到AService 的原始对象–>添加到三级缓存Map<beanName,lamda(beanName,BeanDefinition,AService原始对象)>
2、给bService 属性赋值–>从单例池(一级缓存中)中找bService —> 找不到---->创建BService 的实例
BService 的Bean的生命周期
2.1 class–> 实例化得到BService 的原始对象–>添加到三级缓存
2.2 给aServie 属性赋值—>从单例池中找aService—>找不到—>creatingSet? 存在---->AService 出现了循环依赖---->earlySingtonObjects no----> 从singletonFactories 中找—>lamda表达式-----> 执行---->提前AOP---->产生AService 的代理类对象------>放入二级缓存
getEarlyBeanReference()
2.3 给其他属性赋值
2.4 其他事情 AOP
2.5 将对象放入单例池中
3.给其他属性赋值
4.其余的事情AOP —> AService 的代理类对象---->postPocessAfterInitialazation() 如果之前有了AOP 那么这步省略。
5. earlySingtonObjects.get(‘aService’)
6. creatingSet.remove(‘aService’)
7. 将aService放入单例池中