浅析Spring IoC源码(十一)Spring refresh()方法解析之一

本文深入解析Spring框架中Bean的初始化过程,重点分析AbstractApplicationContext中的refresh()方法,详细介绍了BeanFactoryPostProcessors的执行顺序及getBean方法的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经过上面几节的简单介绍我们了解了spring的一些组件,现在我们来分析一下AbstractApplicationContext中的refresh()这个核心方法吧~


用我们上一节的代码,debug进入refresh方法:

[java]  view plain  copy
  1. public void refresh() throws BeansException, IllegalStateException {  
  2.         synchronized (this.startupShutdownMonitor) {  
  3.             // Prepare this context for refreshing.  
  4.             prepareRefresh();  
  5.   
  6.             // Tell the subclass to refresh the internal bean factory.  
  7.             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();  
  8.   
  9.             // 准备beanfactory来使用这个上下文.做一些准备工作,例如classloader,beanfactoryPostProcessor等  
  10.             prepareBeanFactory(beanFactory);  
  11.   
  12.             try {  
  13.                 //允许上下文的子类去执行postProcessor  
  14.                 postProcessBeanFactory(beanFactory);  
  15.   
  16.                 // 开始执行注册到该上下文的BeanFactoryPostProcessors  
  17.                 invokeBeanFactoryPostProcessors(beanFactory);  
  18.   
  19.                 // 开始注册BeanPostProcessor来拦截其他的bean的初始化过程  
  20.                 registerBeanPostProcessors(beanFactory);  
  21.   
  22.                 // 初始化消息源  
  23.                 initMessageSource();  
  24.   
  25.                 //注册上下文事件的广播集  
  26.                 initApplicationEventMulticaster();  
  27.   
  28.                 //初始化一些特殊的bean  
  29.                 onRefresh();  
  30.   
  31.                 //查询并校验监听器并注册  
  32.                 registerListeners();  
  33.   
  34.                 // 实例化所有非懒加载的所有bean  
  35.                 finishBeanFactoryInitialization(beanFactory);  
  36.   
  37.                 //最后一步发布所有的运用  
  38.                 finishRefresh();  
  39.             }  
  40.   
  41.             catch (BeansException ex) {  
  42.                 // Destroy already created singletons to avoid dangling resources.  
  43.                 destroyBeans();  
  44.   
  45.                 // Reset 'active' flag.  
  46.                 cancelRefresh(ex);  
  47.   
  48.                 // Propagate exception to caller.  
  49.                 throw ex;  
  50.             }  
  51.         }  
  52.     }  

结合上一节我们给出的spring的一些组件实例化的初始化顺序图:


 

我们先看invokeBeanFactoryPostProcessors(beanFactory)这个方法

[java]  view plain  copy
  1. <span style="color:#000000;">protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {  
  2.         // 先执行BeanDefinitionRegistryPostProcessors,因为我们这边没有实现这个接口,先暂时忽略,这段代码  
  3.         Set<String> processedBeans = new HashSet<String>();  
  4.         if (beanFactory instanceof BeanDefinitionRegistry) {  
  5.             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;  
  6.             List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();  
  7.             List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =  
  8.                     new LinkedList<BeanDefinitionRegistryPostProcessor>();  
  9.             for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {  
  10.                 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {  
  11.                     BeanDefinitionRegistryPostProcessor registryPostProcessor =  
  12.                             (BeanDefinitionRegistryPostProcessor) postProcessor;  
  13.                     registryPostProcessor.postProcessBeanDefinitionRegistry(registry);  
  14.                     registryPostProcessors.add(registryPostProcessor);  
  15.                 }  
  16.                 else {  
  17.                     regularPostProcessors.add(postProcessor);  
  18.                 }  
  19.             }  
  20.             Map<String, BeanDefinitionRegistryPostProcessor> beanMap =  
  21.                     beanFactory.getBeansOfType(BeanDefinitionRegistryPostProcessor.classtruefalse);  
  22.             List<BeanDefinitionRegistryPostProcessor> registryPostProcessorBeans =  
  23.                     new ArrayList<BeanDefinitionRegistryPostProcessor>(beanMap.values());  
  24.             OrderComparator.sort(registryPostProcessorBeans);  
  25.             for (BeanDefinitionRegistryPostProcessor postProcessor : registryPostProcessorBeans) {  
  26.                 postProcessor.postProcessBeanDefinitionRegistry(registry);  
  27.             }  
  28.             invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);  
  29.             invokeBeanFactoryPostProcessors(registryPostProcessorBeans, beanFactory);  
  30.             invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);  
  31.             processedBeans.addAll(beanMap.keySet());  
  32.         }  
  33.         else {  
  34.             // Invoke factory processors registered with the context instance.  
  35.             invokeBeanFactoryPostProcessors(getBeanFactoryPostProcessors(), beanFactory);  
  36.         }  
  37.   
  38.         //在beanFactory中获取实现BeanFactoryPostProcessor这个接口的bean的名称  
  39.         String[] postProcessorNames =  
  40.                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.classtruefalse);  
  41.   
  42.         // 将获取到的BeanFactoryPostProcessors的bean分类,根据这些bean是否也实现了PriorityOrdered,Ordered这些接口,或者其他,因为我们的例子中  
  43.         // 并没有实现这些接口,所以我们的"springMultiBean"这个在spring-init.xml中(代码见上一节)定义的bean将进入nonOrderedPostProcessorNames.add(ppName)这个代码块  
  44.         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();  
  45.         List<String> orderedPostProcessorNames = new ArrayList<String>();  
  46.         List<String> nonOrderedPostProcessorNames = new ArrayList<String>();  
  47.         for (String ppName : postProcessorNames) {  
  48.             if (processedBeans.contains(ppName)) {  
  49.                 // skip - already processed in first phase above  
  50.             }  
  51.             else if (isTypeMatch(ppName, PriorityOrdered.class)) {  
  52.                 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));  
  53.             }  
  54.             else if (isTypeMatch(ppName, Ordered.class)) {  
  55.                 orderedPostProcessorNames.add(ppName);  
  56.             }  
  57.             else {  
  58.                 nonOrderedPostProcessorNames.add(ppName);  
  59.             }  
  60.         }  
  61.   
  62.         //首先先执行实现“权重排序”的BeanFactoryPostProcessors,我们的bean“springMultiBean”并没有实现,所以不管  
  63.         OrderComparator.sort(priorityOrderedPostProcessors);  
  64.         invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);  
  65.   
  66.         // 然后执行实现“排序”的接口的BeanFactoryPostProcessors,我们也没有实现,暂时不看这块代码块  
  67.         List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();  
  68.         for (String postProcessorName : orderedPostProcessorNames) {  
  69.             orderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));  
  70.         }  
  71.         OrderComparator.sort(orderedPostProcessors);  
  72.         invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);  
  73.   
  74.         // 最后执行“其他”的BeanFactoryPostProcessors,这边就即将执行我们的springMultiBean这个bean的BeanFactoryPostProcessors  
  75.         // 这边新建了一个List类型是BeanFactoryPostProcessor,好了,这边就开始需要实例化实现BeanFactoryPostProcessor的bean了,否则,  
  76.         // 无法放入List<BeanFactoryPostProcessor> 也就是说,如果想先执行BeanFactoryPostProcessor的方法,必须先实例化实现该接口的bean  
  77.         List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();  
  78.         //可能我们的配置文件有很多的bean实现了BeanFactoryPostProcessors,循环bean的名字  
  79.         for (String postProcessorName : nonOrderedPostProcessorNames) {  
  80.             //底下的方法块是核心块,getBean这个方法就是初始化实现BeanFactoryPostProcessor这个接口的bean了,实例化好了之后放入List<BeanFactoryPostProcessor>  
  81.             nonOrderedPostProcessors.add(getBean(postProcessorName, BeanFactoryPostProcessor.class));  
  82.         }  
  83.         //批量执行nonOrderedPostProcessors中的BeanFactoryPostProcessor  
  84.         invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);  
  85.     }</span>  

好了,到目前为止,我们应该知道了上一节的spring Bean实例化顺序的运行截图了:


也就是我们的上次总结的结论:

①首先执行的是构造函数

②然后执行的BeanNameAware这个接口中的方法

③然后执行的是BeanFactoryAware这个接口中的方法

④执行InitializingBean接口中的afterPropertiesSet的方法

⑤执行我们在xml中定义的init-method这个方法

⑥最后执行的是BeanFactoryPostProcessor这个方法


分析了invokeBeanFactoryPostProcessors这个方法,我们知道这个方法就是去执行BeanFactoryPostProcessor这个接口中的方法去的,上面代码注释也清楚的写到如果想先执行BeanFactoryPostProcessor这个接口的方法,必须先去实例化实现这个接口的Bean,也就是getBean这个方法了,即在执行⑥之前,①~⑤这些方法全是在getBean这个方法中执行的:




我们接着分析一下getBean这个超级核心的方法:

[java]  view plain  copy
  1. <span style="color:#000000;">@SuppressWarnings("unchecked")  
  2.     protected <T> T doGetBean(  
  3.             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)  
  4.             throws BeansException {  
  5.   
  6.         final String beanName = transformedBeanName(name);  
  7.         Object bean;  
  8.   
  9.         // Eagerly check singleton cache for manually registered singletons.  
  10.         Object sharedInstance = getSingleton(beanName);  
  11.         if (sharedInstance != null && args == null) {  
  12.             if (logger.isDebugEnabled()) {  
  13.                 if (isSingletonCurrentlyInCreation(beanName)) {  
  14.                     logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +  
  15.                             "' that is not fully initialized yet - a consequence of a circular reference");  
  16.                 }  
  17.                 else {  
  18.                     logger.debug("Returning cached instance of singleton bean '" + beanName + "'");  
  19.                 }  
  20.             }  
  21.             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);  
  22.         }  
  23.   
  24.         else {  
  25.             // Fail if we're already creating this bean instance:  
  26.             // We're assumably within a circular reference.  
  27.             if (isPrototypeCurrentlyInCreation(beanName)) {  
  28.                 throw new BeanCurrentlyInCreationException(beanName);  
  29.             }  
  30.   
  31.             // Check if bean definition exists in this factory.  
  32.             BeanFactory parentBeanFactory = getParentBeanFactory();  
  33.             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {  
  34.                 // Not found -> check parent.  
  35.                 String nameToLookup = originalBeanName(name);  
  36.                 if (args != null) {  
  37.                     // Delegation to parent with explicit args.  
  38.                     return (T) parentBeanFactory.getBean(nameToLookup, args);  
  39.                 }  
  40.                 else {  
  41.                     // No args -> delegate to standard getBean method.  
  42.                     return parentBeanFactory.getBean(nameToLookup, requiredType);  
  43.                 }  
  44.             }  
  45.   
  46.             if (!typeCheckOnly) {  
  47.                 markBeanAsCreated(beanName);  
  48.             }  
  49.   
  50.             try {  
  51.                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);  
  52.                 checkMergedBeanDefinition(mbd, beanName, args);  
  53.   
  54.                 // Guarantee initialization of beans that the current bean depends on.  
  55.                 String[] dependsOn = mbd.getDependsOn();  
  56.                 if (dependsOn != null) {  
  57.                     for (String dependsOnBean : dependsOn) {  
  58.                         getBean(dependsOnBean);  
  59.                         registerDependentBean(dependsOnBean, beanName);  
  60.                     }  
  61.                 }  
  62.   
  63.                 // Create bean instance.  
  64.                 if (mbd.isSingleton()) {  
  65.                     sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {  
  66.                         public Object getObject() throws BeansException {  
  67.                             try {  
  68.                                 return createBean(beanName, mbd, args);  
  69.                             }  
  70.                             catch (BeansException ex) {  
  71.                                 // Explicitly remove instance from singleton cache: It might have been put there  
  72.                                 // eagerly by the creation process, to allow for circular reference resolution.  
  73.                                 // Also remove any beans that received a temporary reference to the bean.  
  74.                                 destroySingleton(beanName);  
  75.                                 throw ex;  
  76.                             }  
  77.                         }  
  78.                     });  
  79.                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);  
  80.                 }  
  81.   
  82.                 else if (mbd.isPrototype()) {  
  83.                     // It's a prototype -> create a new instance.  
  84.                     Object prototypeInstance = null;  
  85.                     try {  
  86.                         beforePrototypeCreation(beanName);  
  87.                         prototypeInstance = createBean(beanName, mbd, args);  
  88.                     }  
  89.                     finally {  
  90.                         afterPrototypeCreation(beanName);  
  91.                     }  
  92.                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);  
  93.                 }  
  94.   
  95.                 else {  
  96.                     String scopeName = mbd.getScope();  
  97.                     final Scope scope = this.scopes.get(scopeName);  
  98.                     if (scope == null) {  
  99.                         throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");  
  100.                     }  
  101.                     try {  
  102.                         Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {  
  103.                             public Object getObject() throws BeansException {  
  104.                                 beforePrototypeCreation(beanName);  
  105.                                 try {  
  106.                                     return createBean(beanName, mbd, args);  
  107.                                 }  
  108.                                 finally {  
  109.                                     afterPrototypeCreation(beanName);  
  110.                                 }  
  111.                             }  
  112.                         });  
  113.                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);  
  114.                     }  
  115.                     catch (IllegalStateException ex) {  
  116.                         throw new BeanCreationException(beanName,  
  117.                                 "Scope '" + scopeName + "' is not active for the current thread; " +  
  118.                                 "consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",  
  119.                                 ex);  
  120.                     }  
  121.                 }  
  122.             }  
  123.             catch (BeansException ex) {  
  124.                 cleanupAfterBeanCreationFailure(beanName);  
  125.                 throw ex;  
  126.             }  
  127.         }  
  128.   
  129.         // Check if required type matches the type of the actual bean instance.  
  130.         if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {  
  131.             try {  
  132.                 return getTypeConverter().convertIfNecessary(bean, requiredType);  
  133.             }  
  134.             catch (TypeMismatchException ex) {  
  135.                 if (logger.isDebugEnabled()) {  
  136.                     logger.debug("Failed to convert bean '" + name + "' to required type [" +  
  137.                             ClassUtils.getQualifiedName(requiredType) + "]", ex);  
  138.                 }  
  139.                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());  
  140.             }  
  141.         }  
  142.         return (T) bean;  
  143.     }  
  144. </span>  
好吧~,这个getBean的具体实现貌似有点长,一步步分析吧

第一部分:



这个方法首先先去singleton缓存中去找实例(这里我们肯定没找到,应该我们没有把我们的bean手动放入singletonObjects这个Map里面去)

第二部分:


这段代码是先获取该beanFactory父factory,希望从这些factory中获取,如果该beanfactory有父类,则希望用父类去实例化该bean,我们这边的beanfactory为null,暂不讨论~

接着看第三部分:



上图中

第一部分先标记目前的bean的正在创建

第二部分获取根据beanName该bean在beanfactory中的beanDefinitionMap的BeanDefinition,然后去获取这个bean依赖的bean,如果依赖的bean还没有创建,则先创建依赖的bean,递归调用,(Dependence Inject依赖注入的概念吧),如果找不到依赖,则忽略

第三部分:如果是单例(我们暂时只讨论如何创建单例)

则调用createBean()这个方法


好了,我们暂不看Prototype创建的过程,我们接着跟踪createBean()


上图中

第①部分:确保该bean的class是真实存在的,也就是该bean是可以classload可以找到加载的

第②部分:准备方法的重写

第③部分(很重要):请注意,这边有个return,也就是说这边可以返回bean了,但看注释:Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.这边就很清晰了,我们以前在beanPostProcessor的章节讲过,beanPostProcessor是可以临时修改bean的,它的优先级高于正常实例化bean的(也就是第四部分实例化的方法),如果beanPostProcessor能返回,则直接返回了,这边代码下次分析,我们还是先分析主要流程:

看第四部分:

doCreateBean(beanName, mbd, args)这个方法

这个方法首先初始化一个BeanWrapper,然后再看createBeanInstance()





这块代码主要是再次对bean做安全检查并确定该bean有默认的构造函数,createBeanInstance()这个方法最后一行

此时构造函数打印了我们system的内容,也就是第一个打印的



回到doCreateBean()这个方法

初始化bean,的确,现在bean已经实例化了,开始初始化该bean,进入initializeBean(...)这个方法




执行aware方法(看来beanFactoryAware和beanNameAware要执行了)


看源代码果然:

接着



开始执行初始化方法


首先先判断该bean是否实现了InitializingBean,如果实现了先执行afterPropertiesSet这个方法,然后如果该bean又执行了init-method,事实的确如此:


好了,到此为止,我们的第一个名为“springMultiBean"已经初始化了,实例化好的大体步骤我们已经基本了解了,大家先体会一下,我们spring-init.xml中还有一个bean”springOtherBean“没讲解,下次分解~正好一起重新分析细节~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值