spring创建对象的过程(生命周期)
在还没使用spring框架的时候,我们创建对象的时候方式1.类的反射2.new3.instance代码比较重复而且一些必须创建的对象,比如说业务层都需要创建,dao层也需要创建,这样导致我们重复操作了这些事情但是spring容器可以帮我们处理这些繁琐的事情,而且还能加强(具体如何加强后面说到)spring得益于它的IOC和AOP,大大减少我们的琐碎事情下面就来聊聊spring如何帮我们创建对象的!
在还没使用spring框架的时候,我们创建对象的时候方式
1.类的反射
2.new
3.instance
代码比较重复而且一些必须创建的对象,比如说业务层都需要创建,dao层也需要创建,这样导致我们重复操作了这些事情
但是spring容器可以帮我们处理这些繁琐的事情,而且还能加强(具体如何加强后面说到)
spring得益于它的IOC和AOP,大大减少我们的琐碎事情
下面就来聊聊spring如何帮我们创建对象的!!
spring创建对象流程
主要围绕refresh方法讲解,一下是spring官方下载的源码,翻译是参考尚硅谷的添加上去的
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//1 刷新前的预处理
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//2 获取BeanFactory;刚创建的默认DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//3 BeanFactory的预准备工作(BeanFactory进行一些设置)
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 4 BeanFactory准备工作完成后进行的后置处理工作;
// 4.1)、抽象的方法,当前未做处理。子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
postProcessBeanFactory(beanFactory);
/**************************以上是BeanFactory的创建及预准备工作 ****************/
// 5 执行BeanFactoryPostProcessor的方法;
//BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的;
//他的重要两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
//6 注册BeanPostProcessor(Bean的后置处理器)
registerBeanPostProcessors(beanFactory);
// 7 initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 8 初始化事件派发器
initApplicationEventMulticaster();
// 9 子类重写这个方法,在容器刷新的时候可以自定义逻辑;
onRefresh();
// 10 给容器中将所有项目里面的ApplicationListener注册进来
registerListeners();
// 11.初始化所有剩下的单实例bean;
finishBeanFactoryInitialization(beanFactory);
// 12.完成BeanFactory的初始化创建工作;IOC容器就创建完成;
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
1.启动application,执行invokeBeanFactoryPostProcessors(后置工厂处理器)扫描该app下的所有路径的class的注解,controller,service,dao,reporisity,compoment,aspect等注解(还有很多)并且放进一个集合里
2.执行invokeBeanDefinitionRegistryPostProcessors,遍历集合并且生成beandefinition对象,并且进行后续的加强处理,是否含有@lazy注解,@scope注解等,然后存放在一个beanDefinitionMap里(这里的beandefinition对象里是含有该扫描到的类的class)
3.遍历beanDefinitionMap验证bd对象,并且执行finishBeanFactoryInitialization
方法中完成了bean的实例化,调用createBeanInstance完成了推断构造方法和实例化(newInstance,注意此时是实例化,对象属性没注入,还是null的对象,Aware接口的方法没有调用,@PostConstruct方法也没有调用,再一次说明他不是一个完整的bean,继而applyMergedBeanDefinitionPostProcessors方法就是用来处理合并后的beanDefinition对象)
4.判断是否支持循环依赖,如果支持则提前暴露一个工厂对象执行addSingletonFactory。
5.spring会判断是否需要完成属性注入,执行populateBean,里面有判断是否需要注入,如果需要注入用哪种方式,注入方式后面会写一遍文章
循环依赖也在这个方法里面完成的。该方法里面调用了一个非常重要的方法 doGetBean
的方法 (Spring解决循环依赖的方式)
先留意一下这个三个map,解决循环依赖的中间缓存,后面会说到
接下来看一下从map获取对象的过程
/**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从一级缓存里获取bean
Object singletonObject = this.singletonObjects.get(beanName);
//如果这个时候是x注入y,创建y,y注入x,获取x的时候那么x不在容器,具体请查看上面的图addSingletonFactory,此时的x是放在singletonFactory
//第一个singletonObject == null成立
//第二个条件判断是否存在正在创建bean的集合当中,正在创建的bean会先放在一个singletonsCurrentlyInCreation里,成立
//进入if分支
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//先从三级缓存那x?为什么先从三级缓存拿?
//为什么要从三级缓存里拿?在这个方法明明是put到factory二级缓存里去了addSingletonFactory,所以这里的singletonObject==null,allowEarlyReference先不说,是true,所以进入分支
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
//1.1
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
//1.1和这一行之所以这样写是加快性能,第一次判断不上锁,第二次判断才上锁,判断相同的条件,类似于单例模式
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
从二级缓存中获取一个 singletonFactory,回顾前文,能获取到
//由于这里的beanName=x,故而获取出来的工厂对象,能产生一个x半成品状态bean(属性还没注入,或者注入了一部分)
singletonObject = singletonFactory.getObject();
//拿到了半成品的xbean之后,把他放到三级缓存;
this.earlySingletonObjects.put(beanName, singletonObject);
//然后从二级缓存清除掉x的工厂对象;
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
然后这里是上升为一级缓存
/**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
//上升为一级缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
6. 至此一个bean完成初始化,被put到单例池,这说明一个bean在spring容器当中被创建出来是有一个过程的,这个过程就是所谓的bean的生命周期,我们的循环依赖也是在这个生命周内完成的。
最后附上简单的图
更多推荐
所有评论(0)