1.bean的创建过程:
- 主要过程:UserService-->构造方法(推断构造方法)-->对象(里面的OrderService属性没有值)-->依赖注入(属性赋值)-->初始化前(
@PostConstruct)-->初始化(实现InitializingBean)-->初始化后(AOP->代理对象)-->Bean - 对象 instance of InitializingBean 判断是否实现该类
- 构造方法的参数对象查找:spring查找容器bean先通过对象类型查找,如果有多个,再根据名字查找
- UserServiceProxy(cglib)--->代理对象--->代理对象.target=普通对象
- 代理对象.test();
class UserServiceProxy extends UserService{
UserService target;
public void test(){
//执行切面@Before (缓存map获取方法)
target.test();
}
}
- 判断是否要进行AOP代理对象创建:
- 找出所有的切面Bean
- 遍历
- 遍历方法
- 方法===》UserService 缓存map
- 判断是否创建事务代理对象:
- 事务@transactional
- 创建一个数据库连接conn(事务管理器dataSource)
- conn.autocommit=false
- 执行原方法sql
- conn.commit();
- conn.rollback();
- 方法调用事务失效:看调用对象是否是代理对象,是的话就不会失效
- 不加@Configuration注解事务会失效:加注解是保证只有一个dataSource,执行原方法sql和事务管理器dataSource是一个。 AppConfig代理对象去容器里面拿dataSource
2.手写模拟Spring底层原理
1.Spring的底层源码启动过程
@Scope("prototype")原型=多例- 创建applicationContext对象,根据入参配置类的配置的扫描地址扫描包路径
- 通过扫描class类判断是否有
@component注解 - 如果有注解就创建
BeanDefinition对象存储到BeanDefinitionMap里面 - 根据
BeanDefinition创建单例bean存储在singletonMap里面 - 在
getBean的时候如果是原型bean创建原型bean并返回,如果是单例bean从singletonMap里面获取bean并返回 - 依赖注入
- 初始化->实现
InitializingBean接口 - 初始化前后->实现
BeanPostProcessor接口
2.BeanDefinition,BeanPostProcessor的作用
- BeanDefinition:type,scope,isLazy
- BeanPostProcessor:初始化后可以创建AOP的动态代理对象,初始化前可以自定义注解实现自己的功能
- 定义bean:@Bean @component
Map<String,BeanDefinition>Map<String,Object>List<BeanPostProcessor>
3.Aware回调的应用
BeanNameAware回调,BeanFactoryAware回调 在初始化之前执行
3.依赖注入解决方案
Aservice出现了循环依赖的情况下,才需要提前进行AOP
- 先创建AService,执行AService的生命周期
- creatingSet
- 实例化AService-->得到一个对象-->singletonFactories<AService:lambda<AService原始对象>>
- 填充BService属性-->去单例池中找BService-->singletonObjects--->没有则创建BService
- 填充cService属性
- 初始化前、初始化
- 初始化后-->AService代理对象
- 放入单例池
- 创建BService,执行BService的生命周期
- 实例化BService-->得到一个对象-->singletonFactories<BService :lambda< Bservice原始对象>>
- 填充AService属性->去单例池中找aervice-->creatingset->出现了循环依赖-->eanrlysingletonobjects->singletonfactories->Lambda->执行->earlysingletonobiect
- 填充其他属性
- 初始化前、初始化
- 初始化后
- 放入单例池
- 创建cService,执行BService的生命周期
- 实例化BService-->得到一个对象-->singletonFactories<CService : lambda<CService原始对象>>
- 填充AService属性-->去单例池中找AService-->creatingSet-->出现了循环依赖-->earlySingletonobjects
- 填充其他属性
- 初始化前、初始化
- 初始化后
- 放入单例池
- 三级缓存的作用:
- singletonObjects:缓存经过了完整生命周期的bean
- earlysingletonObjects:缓存未经过完整生命周期的bean,如果某个bean出现了循环依赖,就会提前把这暂时未经过完整生命周期的bean放入earlySingletonObjects中,这个bean如果要经过AOP,那么就会把代理对象放入earlySingletonObiects中,否则就是把原始对象放入earlyingletonObjects,但是不管怎么样,就是是代理对象,代理对象所代理的原始对象也是没有经过完整生命周期的,所以放earlySingletonObjects我们就可以统一认为是未经过完整生命周期的bean
- singletonFactories:缓存的是一个0bjectFactory,也就是一个Lambda表达式。在每个Bean的生成过程中,经过实例化得到一个原始对象后,都会提前基于原始对象暴露一个Lambda表达式,并保存到三级缓存中,这个Lambda表达式可能用到,也可能用不到,如果当前Bean没有出现循环依赖,那么这个Lambda表达式没用,当前bean按照自己的生命周期正常执行,执行完后直接把当前bean放入singletonObjects中,如果当前bean在依赖注入时发现出现了循环依赖(当前正在创建的bean被其他bean依赖了),则从三级缓存中拿到Lambda表达式,并执行Lambda表达式得到一个对象,并把得到的对象放入二级缓存((如果当前Bean需要AOP,那么执行lambda表达式,得到就是对应的代理对象,如果无需AOP,则直接得到一个原始对象))。
- 其实还要一个缓存,就是earlyProxyReferences,它用来记录某个原始对象是否进行过AOP了。