spring创建对象的过程(生命周期)

spring创建对象的过程(生命周期),第1张

在还没使用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.
	 * 

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的生命周期,我们的循环依赖也是在这个生命周内完成的。

最后附上简单的图

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/786169.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存