Bean的生命周期
BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。
1)根据配置情况调用 Bean 构造方法或工厂方法实例化 Bean。
2)利用依赖注入完成 Bean 中所有属性值的配置注入。
3)如果 Bean 实现了 BeanNameAware 接口,则 Spring 调用 Bean 的 setBeanName() 方法传入当前 Bean 的 id 值。
4)如果 Bean 实现了 BeanFactoryAware 接口,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用。
5)如果 Bean 实现了 ApplicationContextAware 接口,则 Spring 调用 setApplicationContext() 方法传入当前 ApplicationContext 实例的引用。
6)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的预初始化方法 postProcessBeforeInitialzation() 对 Bean 进行加工操作,此处非常重要,Spring 的 AOP 就是利用它实现的。
7)如果 Bean 实现了 InitializingBean 接口,则 Spring 将调用 afterPropertiesSet() 方法。
8)如果在配置文件中通过 init-method 属性指定了初始化方法,则调用该初始化方法。
9)如果 BeanPostProcessor 和 Bean 关联,则 Spring 将调用该接口的初始化方法 postProcessAfterInitialization()。此时,Bean 已经可以被应用系统使用了。
10)如果在 <bean> 中指定了该 Bean 的作用范围为 scope="singleton",则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在 <bean> 中指定了该 Bean 的作用范围为 scope="prototype",则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
11)如果 Bean 实现了 DisposableBean 接口,则 Spring 会调用 destory() 方法将 Spring 中的 Bean 销毁;如果在配置文件中通过 destory-method 属性指定了 Bean 的销毁方法,则 Spring 将调用该方法对 Bean 进行销毁。
三级缓存问题
getBean()==>doGetBean()==>createBean()==>doCreateBean()
创建Bean的部分源码如下
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { ... @Override @Nullable public Object getSingleton(String beanName) { return getSingleton(beanName, true); } @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { //1.先从一级缓存中获取,获取到直接返回 Object singletonObject = this.singletonObjects.get(beanName); //2.如果获取不到或对象正在创建,就到二级缓存中去获取,获取到直接返回 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { singletonObject = this.earlySingletonObjects.get(beanName); //3.如果仍获取不到,且允许 singletonFactories(allowEarlyCurrentlyInCreation())通过 getObject()获取。 //就到三级缓存中用 getObject() 获取。 //获取到就从 singletonFactories中移出,且放进 earlySingletonObjects。 //(即从三级缓存移动到二级缓存) if (singletonObject == null && allowEarlyReference) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; } ... public boolean isSingletonCurrentlyInCreation(String beanName) { return this.singletonsCurrentlyInCreation.contains(beanName); } protected boolean isActuallyInCreation(String beanName) { return isSingletonCurrentlyInCreation(beanName); } ... }
三级缓存的源码
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { ... // 从上至下 分表代表这“三级缓存” private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); //一级缓存 private final Map<String, Object> earlySingletonObjects = new HashMap<>(16); // 二级缓存 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); // 三级缓存 ... /** Names of beans that are currently in creation. */ // 这个缓存也十分重要:它表示bean创建过程中都会在里面呆着~ // 它在Bean开始创建时放值,创建完成时会将其移出~ private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); /** Names of beans that have already been created at least once. */ // 当这个Bean被创建完成后,会标记为这个 注意:这里是set集合 不会重复 // 至少被创建了一次的 都会放进这里~~~~ private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256)); }
singletonsCurrentlyInCreation:
在实例化之前存入,添加到singletonObjects之后删除,用于判断bean对象是否正在创建
alreadyCreated:
Bean被创建完成后,会进入,表示Bean被创建过至少一次
一级缓存:singletonObject = ConcurrentHashMap<>(256)
存放以及初始化完成后的单例对象或者代理对象(如果对象需要被代理),可以直接使用的Bean
二级缓存:earlySingletonObject = HashMap<>(16)
存放出现循环依赖后被创建的代理对象(保证单例)或者普通对象(没有经过完整生命周期的bean)
三级缓存:singletonFactories = HashMap<>(16)
在实例化对象之后,属性注入之前会将对象放入singletonFactories,用于打破循环
为什么要包装一个ObjectFactory对象?
如果创建的Bean有对应的aop代理,那其他对象注入时,注入的应该是对应的代理对象;「但是Spring无法提前知道这个对象是不是有循环依赖的情况」,而正常情况下(没有循环依赖情况),Spring都是在对象初始化后才创建对应的代理。这时候Spring有两个选择:
- 不管有没有循环依赖,实例化后就直接创建好代理对象,并将代理对象放入缓存,出现循环依赖时,其他对象直接就可以取到代理对象并注入(只需要2级缓存,singletonObjects和earlySingletonObjects即可)
- 不提前创建好代理对象,在出现循环依赖被其他对象注入时,才提前生成代理对象(此时只完成了实例化)。这样在没有循环依赖的情况下,Bean还是在初始化完成才生成代理对象(需要3级缓存)
所以3级缓存的作用
- 为了正常情况下,代理对象能在初始化完成后生成,而不用提前生成
- 在对象需要被代理的时候提前生成代理对象,如果有其他bean对象需要这个普通对象时就将代理对象注入属性,否则如果注入的属性是普通对象的话,而被注入的类对象的引用指向的是一个普通对象,代理逻辑就不会执行
Spring事务管理
Spring提供上层接口PlatformTransactionManager,然后通过其实现类来做事务(Mybatis使用DateSourceTransactionManager,Hibernate使用HibernateTransactionManager),底层都是使用AOP完成
通过AOP实现,在代理对象里面获取connection,然后存入ThreadLocal,在执行super的方法,super去ThreadLocal获取代理对象存入的connection,保证拿到的是同一个connection,在决定是否抛异常和回滚
编程式事务
在代码里面声明,先开启事务,执行事务,是否提交事务
声明式事务
基于注解
基于xml
传播特性(propagation)
PROPAGATION_REQUIRED:
如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,这是最常见的选择,也是Spring默认的事务传播行为。(required需要,没有新建,有加入)
PROPAGATION_SUPPORTS:
支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。(supports支持,有则加入,没有就不管了,非事务运行)
PROPAGATION_MANDATORY:
支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。(mandatory强制性,有则加入,没有异常)
PROPAGATION_REQUIRES_NEW:
创建新事务,无论当前存不存在事务,都创建新事务。(requires_new需要新的,不管有没有,直接创建新事务)
PROPAGATION_NOT_SUPPORTED:
以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。(not supported不支持事务,存在就挂起)
PROPAGATION_NEVER:
以非事务方式执行,如果当前存在事务,则抛出异常。(never不支持事务,存在就异常)
PROPAGATION_NESTED:
如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。(nested存在就在嵌套的执行,没有就找是否存在外面的事务,有则加入,没有则新建)
.
标签:事务,缓存,对象,spring,beanName,Bean,Spring From: https://www.cnblogs.com/happy12123/p/16813337.html