Spring Boot 源码分析(四):IOC容器刷新

291 阅读25分钟

前面说到SpringApplication的run方法执行时会刷新IOC容器,最终都会调AbstractApplicationContext的refresh方法。下面我们聚焦这个方法,看看容器刷新全流程是怎样的。

将refresh拆解开来分析:

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
            //1.刷新前的准备
			prepareRefresh();

            //2.让AbstractApplicationContext的子类“刷新”它内部持有的Beanfactory并返回
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //3.配置AbstractApplicationContext持有的beanFactory
			prepareBeanFactory(beanFactory);

			try {
                //4.BeanFactory的后置处理
				postProcessBeanFactory(beanFactory);

                //5.调用BeanFactoryPostProcessor
				invokeBeanFactoryPostProcessors(beanFactory);

                //6.注册BeanPostProcessor
				registerBeanPostProcessors(beanFactory);

                //7.初始化国际化组件
				initMessageSource();

                //8.初始化事件广播器
				initApplicationEventMulticaster();

                //9.初始化ApplicationConext子类中其他特殊bean
				onRefresh();

				// 10.注册监听器
				registerListeners();

				// 11.初始化剩余单例Bean
				finishBeanFactoryInitialization(beanFactory);

				// 12.刷新后的动作
				finishRefresh();
			}

			catch (BeansException ex) {
				//处理异常
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}

			finally {
				// 重置缓存
				resetCommonCaches();
			}
		}
	}

1. prepareRefresh:刷新前的准备

protected void prepareRefresh() {
		//设置标志位
		this.closed.set(false);
		this.active.set(true);

		// 初始化属性
		initPropertySources();

		//验证属性
		getEnvironment().validateRequiredProperties();

		//兼顾可重复刷新IOC容器的情况
		if (this.earlyApplicationListeners == null) {
            //首次刷新,把所有监听器赋值给一个新变量:早期监听器
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
			// 重复刷新时,把早期监听器再赋值回所有监听器变量
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

		// 早期事件集合,等待事件广播器去广播
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}
  • 初始化属性。

    	protected void initPropertySources() {
    		// For subclasses: do nothing by default.
    	}
    

    模板方法,供子类重写。前面说到ApplicationContext类体系时说到,AbstractApplicationContext的子类GenericWebApplicationContext对应注解驱动方式,子类AbstractRefreshableWebApplicationContext对应XML配置方式。

    Spring Boot主要支持注解驱动,所以看下GenericWebApplicationContext的initPropertySources:

        protected void initPropertySources() {
            ConfigurableEnvironment env = this.getEnvironment();
            if (env instanceof ConfigurableWebEnvironment) {
                ((ConfigurableWebEnvironment)env).initPropertySources(this.servletContext,null);
            }
        }
    

    initPropertySources先获取Environment,然后调Environment的initPropertySources。我们讨论的WebApplicationType是SERVLET,对应环境具StandardServletEnvironment,它的initPropertySources:

        public void initPropertySources(@Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
            //getPropertySources返回Environment中的一个MutablePropertySources类型属性
            WebApplicationContextUtils.initServletPropertySources(this.getPropertySources(), servletContext, servletConfig);
        }
    

工具类WebApplicationContextUtils:

    public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) {
        Assert.notNull(sources, "'propertySources' must not be null");
        String name = "servletContextInitParams";
        if (servletContext != null && sources.get(name) instanceof StubPropertySource) {
            sources.replace(name, new ServletContextPropertySource(name, servletContext));
        }

        name = "servletConfigInitParams";
        if (servletConfig != null && sources.get(name) instanceof StubPropertySource) {
            sources.replace(name, new ServletConfigPropertySource(name, servletConfig));
        }

    }

Servlet规范中,每个Servlet都可以有自己的初始化配置,ServletConfig是Servlet的配置对象,所以每个Servlet都有自己的ServletConfig;每个应用也有自己的配置,ServletContext是整个应用的配置对象,所以每个Servlet只有一个ServletContext。这里的初始化属性就是将这两种不同的配置对象设置到环境中。

2.obtainFreshBeanFactory

	protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

先调用refreshBeanFactory,这是模板方法,需要AbstractApplicationContext重写,

GenericWebApplicationContext的重写:

	protected final void refreshBeanFactory() throws IllegalStateException {
        //CAS,控制下面的部分只能执行一次
		if (!this.refreshed.compareAndSet(false, true)) {
			throw new IllegalStateException(
					"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
		}
        //只是简单的设置了beanFactory的序列化id
		this.beanFactory.setSerializationId(getId());
	}

AbstractRefreshableWebApplicationContext的重写:

	protected final void refreshBeanFactory() throws BeansException {
        //关闭前一个beanFactory(如果有的话)
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
            //真正实例化一个beanFactory并加载Bean定义到beanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
			beanFactory.setSerializationId(getId());
			customizeBeanFactory(beanFactory);
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		//catch ...
	}

两种不同iApplicationContext的getBeanFactory大致相同。

3. prepareBeanFactory:预处理beanFactory

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// 配置beanFactory的类加载器等
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		//注册一个BeanPostProcessor,用来处理ApplicationContext
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// 自动注入相关类
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// 注册一个BeanPostProcessor,用来加载所有事件监听器
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// 对LoadTimeWeaver的支持
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// 注册environment相关bean
		if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}
  • ApplicationContextAwareProcessor,关注下它的回调逻辑:

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		//如果处理的bean不是下面Aware接口类型,返回。说明回调逻辑就是要处理实现了下面这些Aware接口的bean
        	if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
    			  bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
    			  bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
    			return bean;
    		}
    		
        	//如果当前bean实现了这些Aware接口,就把容器applicationContext或容器的其他属性设置到后置处理器要处理的bean
        	//Aware接口设计的意图,就是用它的的setter把框架底层的一些对象注入到要处理的bean中,供开发者使用
    		invokeAwareInterfaces(bean);
    
    		return bean;
    	}
    
    	private void invokeAwareInterfaces(Object bean) {
    		if (bean instanceof EnvironmentAware) {
    			((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    		}
    		if (bean instanceof EmbeddedValueResolverAware) {
    			((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    		}
    		if (bean instanceof ResourceLoaderAware) {
    			((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    		}
    		if (bean instanceof ApplicationEventPublisherAware) {
    			((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    		}
    		if (bean instanceof MessageSourceAware) {
    			((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    		}
    		if (bean instanceof ApplicationContextAware) {
    			((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    		}
    	}
    

    这个后置处理类已经处理了这些接口,就不用再处理了,所以下面就用beanFactory的ignoreDependencyInterface,忽略这些接口。

  • 自动注入相关类。

    跟进源码可看到DefaultListableBeanFactory这个IOC容器的唯一落地实现类是如何处理的。

    private final Map<Class<?>, Object> resolvableDependencies;
    
    public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {
            if (autowiredValue != null) {
                if (!(autowiredValue instanceof ObjectFactory) && !dependencyType.isInstance(autowiredValue)) {
                    throw new IllegalArgumentException("Value [" + autowiredValue + "] does not implement specified dependency type [" + dependencyType.getName() + "]");
                }
    			//容器内部用了一个Map缓存被指定接口和对应实现类的映射关系
                this.resolvableDependencies.put(dependencyType, autowiredValue);
            }
    
        }
    
  • ApplicationListenerDetector,这个BeanPostPocessor处理事件监听器,bean初始化前加入容器,摧毁前从容器中移除:

    //初始化前回调
    public Object postProcessAfterInitialization(Object bean, String beanName) {
    		if (bean instanceof ApplicationListener) {
                //如果处理bean是事件监听器类型ApplicationListener,且是单例,就把它加入到容器中
    			Boolean flag = this.singletonNames.get(beanName);
    			if (Boolean.TRUE.equals(flag)) {
    				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
    			}
    			else if (Boolean.FALSE.equals(flag)) {
    				this.singletonNames.remove(beanName);
    			}
    		}
    		return bean;
    	}
    
    	public void addApplicationListener(ApplicationListener<?> listener) {
            //容器中有事件广播器对象,这个对象的有个内部类可以把监听器加入
    		if (this.applicationEventMulticaster != null) {
    			this.applicationEventMulticaster.addApplicationListener(listener);
    		}
    		this.applicationListeners.add(listener);
    	}
    
    //bean摧毁前回调:
    	public void postProcessBeforeDestruction(Object bean, String beanName) {
    		if (bean instanceof ApplicationListener) {
    			try {
                    //容器中的事件广播器移除监听器
    				ApplicationEventMulticaster multicaster = this.applicationContext.getApplicationEventMulticaster();
    				multicaster.removeApplicationListener((ApplicationListener<?>) bean);
    				multicaster.removeApplicationListenerBean(beanName);
    			} //catch...
    		}
    	}
    

4. postProcessBeanFactory:BeanFactory的后置处理

读取源码文档,这一步可以在ApplicationContext内部的beanFactory被标准初始化后修改它,这一阶段所有bean定义已经加载,但没有bean会在此实例化成一个对象。同时这一步也允许注册某些特殊的BeanPostProcessor。这个方法也是模板方法,关注下GenericWebApplicationContext,发现会向beanFactory注入Servlet相关的BeanPostProcessor和Servlet中一些域对象等。

    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        if (this.servletContext != null) {
            beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
            beanFactory.ignoreDependencyInterface(ServletContextAware.class);
        }

        WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
        WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
    }

先来看看ServletContextAwareProcessor的后置处理回调逻辑,就是简单的判断如果bean是ServletContextAware类型或ServletConfigAware类型,则会把ServletContext和ServletConfig这些底层对象注入bean。

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (this.getServletContext() != null && bean instanceof ServletContextAware) {
            ((ServletContextAware)bean).setServletContext(this.getServletContext());
        }

        if (this.getServletConfig() != null && bean instanceof ServletConfigAware) {
            ((ServletConfigAware)bean).setServletConfig(this.getServletConfig());
        }

        return bean;
    }

再来看WebApplicationContextUtils的registerWebApplicationScopes,发现也是简单的向beanFactory注入request、session等域对象的FactoryBean。通过FactoryBean的getObject方法可以返回对应对象。

public abstract class WebApplicationContextUtils {
    
    public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory, @Nullable ServletContext sc) {
        beanFactory.registerScope("request", new RequestScope());
        beanFactory.registerScope("session", new SessionScope());
        if (sc != null) {
            ServletContextScope appScope = new ServletContextScope(sc);
            beanFactory.registerScope("application", appScope);
            sc.setAttribute(ServletContextScope.class.getName(), appScope);
        }

        beanFactory.registerResolvableDependency(ServletRequest.class, new WebApplicationContextUtils.RequestObjectFactory());
        beanFactory.registerResolvableDependency(ServletResponse.class, new WebApplicationContextUtils.ResponseObjectFactory());
        beanFactory.registerResolvableDependency(HttpSession.class, new WebApplicationContextUtils.SessionObjectFactory());
        beanFactory.registerResolvableDependency(WebRequest.class, new WebApplicationContextUtils.WebRequestObjectFactory());
        if (jsfPresent) {
            WebApplicationContextUtils.FacesDependencyRegistrar.registerFacesDependencies(beanFactory);
        }
	}      
        
    //FactoryBean
    private static class RequestObjectFactory implements ObjectFactory<ServletRequest>, Serializable {
       
        public ServletRequest getObject() {
            return WebApplicationContextUtils.currentRequestAttributes().getRequest();
        }
   	 }
  
}

最后看registerEnvironmentBeans,也是很简单的把ServletContext、ServletConfig和把它们的属性封装到Map中后注入beanFactory。

WebMvc环境中的容器,调用父类方法后,会处理手动编码的注解类和@Component标注类。

public class AnnotationConfigServletWebServerApplicationContext {
    private final AnnotatedBeanDefinitionReader reader;
	private final ClassPathBeanDefinitionScanner scanner;

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        super.postProcessBeanFactory(beanFactory);
        if (this.basePackages != null && this.basePackages.length > 0) {
            this.scanner.scan(this.basePackages);
        }

        if (!this.annotatedClasses.isEmpty()) {
            this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
        }
    }
    
    //...
}

5.调用BeanFactory后置处理器

这部分的源码很长,反复阅读可以梳理出整体流程。直接取出beanFactory中所有BeanFactory后置处理器,然后调用代理类的同名方法:

	protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	}

PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors:

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		Set<String> processedBeans = new HashSet<>();

    	//beanFactory是bean定义注册器
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            //用2个集合分类收集BeanFactory后置处理器
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
                    //BeanDefinitionRegistryPostProcessor立即回调后置处理逻辑
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else {
					regularPostProcessors.add(postProcessor);
				}
			}
            
            //...
        } else {
         invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
     }

由前面类图知道现在讨论的BeanFactory根接口的唯一落地实现类DefaultListableBeanFactory实现了BeanDefinitionRegistry,所以if判断成立。Debug时发现方法第二个参数只有3个:

1-4.jpg

这几个是创建SpringApplication对象,设置初始化器和事件监听器时加进去的,它们是初始化器或事件监听器的内部类,点开源码可见它们都是通过ConfigurableApplicationContext的addBeanFactoryPostProcessor这一途径注入到容器的。如之前所过的ConfigFileApplicationListener:

public class ConfigFileApplicationListener implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
    //...
    protected void addPostProcessors(ConfigurableApplicationContext context) {
        context.addBeanFactoryPostProcessor(new ConfigFileApplicationListener.PropertySourceOrderingPostProcessor(context));
    }
    //...
}   

执行到上面的if分支时,前两个被收集到registryProcessors集合,最后一个被收集到regularPostProcessors。这2个集合分别存放BeanDefinitionRegistryPostProcessor和普通的BeanFactoryPostProcessor。

继续跟踪if分支,会按照PriorityOrdered, Ordered和其他排序优先级分离**非上述途径(如开发者编写的)**获得的BeanDefinitionRegistryPostProcessor,每一优先级内再排序,然后按序执行回调方法。

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		Set<String> processedBeans = new HashSet<>();

    	//如果beanFactory同时是bean定义注册器
		if (beanFactory instanceof BeanDefinitionRegistry) {
			// ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的BeanDefinitionRegistryPostProcessor的处理...
            
            //非上述方式
            List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
            //排序并回调PriorityOrdered序列优先级的bean定义注册器后置处理器
			//...

			
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
				}
			}
			//排序并回调Ordered序列优先级的bean定义注册器后置处理器
            //...

			
			boolean reiterate = true;
			while (reiterate) {
				reiterate = false;
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
					if (!processedBeans.contains(ppName)) {
						currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
						processedBeans.add(ppName);
						reiterate = true;
					}
				}
				//排序并回调其他序列优先级的bean定义注册器后置处理器
           		 //...
			}

			// 回调所有的postProcessBeanFactory逻辑
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
        } else {
         invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
     }
    

因为BeanDefinitionRegistryPostProcessor同时还是BeanFactoryPostProcessor,所以以上完成后还要回调上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,普通的BeanFactoryPostProcessor的postProcessBeanFactory方法也要回调。

到这里先整理流程再继续分析:

  • 先回调ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的BeanDefinitionRegistryPostProcessor;

  • 再回调其他途径注入的BeanDefinitionRegistryPostProcessor,具体会按照不同的排序优先级依次回调;

  • 再回调所有BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法;

  • 最后回调ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的普通BeanFactoryPostProcessor的postProcessBeanFactory方法。

if分支执行完毕,接着会按着处理BeanDefinitionRegistryPostProcessor的思路,对非ConfigurableApplicationContext的addBeanFactoryPostProcessor方法注入的BeanFactoryPostProcessor,按照PriorityOrdered, Ordered和其他排序优先级分离,并依次按序执行回调。ConfigurableApplicationContext的addBeanFactoryPostProcessor方式注入的没有这3种排序优先级,非这种方式有。

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

		Set<String> processedBeans = new HashSet<>();

		// if... else ...
    
    	String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		
    	//先收集3种不同优先级的
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 再分别回调3种
     }
}
    

所有类型的bean定义后置处理器和普通的BeanFactoryPostProcessor都处理完了,逻辑完整。这里一定要边Debug边梳理,否则容易被绕晕:

其中有个BeanDefinitionRegistryPostProcessor是处理配置类的,它是ConfigurationClassPostProcessor。Spring Boot自动装配的和开发者用@Configuration和@Component等注解注册的bean都是通过这个后置处理类完成注册到容器。

1-4a.jpg

6. registerBeanPostProcessors:注册BeanPostProcessor

这部分源码看起来和BeanFactoryPostProcessor很想,也是通过PostProcessorRegistrationDelegate的静态方法实现:

	protected void registerBeanPostProcessors(ConfigurableListableBeanFFF beanFactory) {
		PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
	}

继续分析:

	public static void registerBeanPostProcessors(
			ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

		String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

		// 注册BeanPostProcessorChecker
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		//按照PriorityOrdered、Ordered和普通排序优先级分离BeanPostProcessor
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
                //PriorityOrdered类型的通过beanFactory的getBean,这里会真正初始化!
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
                //单独收集MergedBeanDefinitionPostProcessore类型的BeanPostProcessor
				if (pp instanceof MergedBeanDefinitionPostProcessor) {
					internalPostProcessors.add(pp);
				}
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else {
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// 收集完成后先注册PriorityOrdered的BeanPostProcessor
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// 接着注册PriorityOrdered的
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String ppName : orderedPostProcessorNames) {
            //同样会初始化
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
            //同样收集MergedBeanDefinitionPostProcessor类型的
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// 然后注册普通的BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// 最后注册上面3步收集的MergedBeanDefinitionPostProcessor类型的BeanPostProcessor
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// 再次注册ApplicationListenerDetector,这里重复注册实际是把它移到后置处理器末尾
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

7.初始化国际化组件

protected void initMessageSource() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
    	//容器里名称是messageSource的bean,直接赋值
		if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
			this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
			if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
				HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
				if (hms.getParentMessageSource() == null) {
					hms.setParentMessageSource(getInternalParentMessageSource());
				}
			}
		}
		else {
			// 没有就直接创建一个然后注册到容器
			DelegatingMessageSource dms = new DelegatingMessageSource();
			dms.setParentMessageSource(getInternalParentMessageSource());
			this.messageSource = dms;
			beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
		}
	}

8.初始化事件广播器

和初始化国际化支持的组件如出一辙,都是先检查容器里是否有响应名称的bean,有则注入,无则创建一个然后注册。

protected void initApplicationEventMulticaster() {
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
			this.applicationEventMulticaster =
					beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
		}
		else {
			this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
			beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
		}
	}

9.初始化ApplicationConext子类中其他特殊bean

模板方法,供ApplicationContext子类重写的,在单列bean实例化之前初始化一些bean。

10.注册监听器

protected void registerListeners() {
		// 先把IOC容器中一组ApplicationListener对象取出,添加到事件广播器
		for (ApplicationListener<?> listener : getApplicationListeners()) {
			getApplicationEventMulticaster().addApplicationListener(listener);
		}

		// 从容器中取出ApplicationListener类型bean的名称,添加到事件广播器
    	//这里没有用beanFactory的getBean方法获取bean对象,是为了防止监听器被过早初始化,单例bean初始化在下一动作中完成
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// 第一步的早期事件这时可以被广播了
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
			for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
				getApplicationEventMulticaster().multicastEvent(earlyEvent);
			}
		}
	}

11.finishBeanFactoryInitialization:初始化剩余单例Bean

11.1 getBean

先总体看一下finishBeanFactoryInitialization的实现,重点聚焦在方法最后一行。

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 初始化ConversionService
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

        //注册一个默认的嵌入式值解析器,负责解析占位符和表达式
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 初始化LoadTimeWeaverAware
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}
		beanFactory.setTempClassLoader(null);

		// 冻结配置
		beanFactory.freezeConfiguration();

        //实例化所有非懒加载的单例bean
		beanFactory.preInstantiateSingletons();
	}

preInstantiateSingletons最终实现在DefaultListableBeanFactory中。点开源码,看到while死循环循环内嵌套多个do...while...循环,也是让人头大:fearful:,下面把代码折叠一下就方便分析了。在最外层while死循环的内部,先把嵌套的首层do...while...折叠一下,会发现这是用bean对象在判断,如果bean的类型不是工厂bean,就执行非工厂bean的处理逻辑。如果bean类型是工厂bean,那么bean默认不立即初始化,除非isEagerInit是true,才调用getBean初始化。首次进入while死循环,bean变量值null,肯定执行非工厂bean的逻辑。

1-5.jpg

下面展开非工厂bean对应代码,发现又是一个while死循环,内部先嵌套几层do...while...循环,再根据bean名称而不是根据bean对象判断是否工厂bean,如果是就直接获取然后退出非工厂bean的while死循环。最后又出现一个熟悉的getBean方法。先看内部的几个do...while...,如下图分析,会先执行最内部的do循环体。通常容器的beanDefinitionNames不为空,所以最内部循环体的if先不执行,直接获取第一个beanNane,然后根据这个bean名称获取bean的合并bean定义。根据这个bean定义判断,如果抽象、非单例、懒加载3个条件任何一个满足都会继续执行最内部循环体。反之那些非抽象、单例且非懒加载的bean会走出这几个do...while...,然后根据bean名称判断是否工厂bean。如果根据名称判断确实是工厂bean,会退出内层while死循环,然后继续执行工厂bean的处理逻辑,最后会继续执行最外层的while循环,重复上面的流程;如果根据名称判断不是工厂bean,那就直接getBean了。

所以最内层的嵌套do...while...只是筛选作用。

1-6.jpg

非工厂bean中那些非抽象、单例的并且非懒加载的bean,会执行getBean(beanName),进一步跟进,会调AbstractBeanFactory的方法:

    public Object getBean(String name) throws BeansException {
        return this.doGetBean(name, (Class)null, (Object[])null, false);
    }
11.2 doGetBean

我们再跟进doGetBean的逻辑,它的内部较长,分开看。

  1. 循环依赖的处理

    protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
        	//名称处理,不是关注点
            String beanName = this.transformedBeanName(name);
        	//
            Object sharedInstance = this.getSingleton(beanName);
            Object bean;
            if (sharedInstance != null && args == null) {
               //logger...
                bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
            }
    

    getSingleton方法会从缓存中获取当前正在获取的单例bean,和循环依赖处理有关。如果从缓存中取到,会对FactoryBean类型额外处理。

  2. 创建前检查和其他处理。

//...
else {
    		//原型bean相互依赖会引起无限循环,抛出异常
            if (this.isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

    		//本地不存在bean定义,就让父beanFactory实例化
            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                String nameToLookup = this.originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
             }
                
				//...
                return parentBeanFactory.getBean(nameToLookup);
            }

            
  1. 标记当前bean已创建。

    	//...
    	if (!typeCheckOnly) {
         	this.markBeanAsCreated(beanName);
    	}
    
        protected void markBeanAsCreated(String beanName) {
            if (!this.alreadyCreated.contains(beanName)) {
            //加锁,保证安全
                synchronized(this.mergedBeanDefinitions) {
                    if (!this.alreadyCreated.contains(beanName)) {
                        this.clearMergedBeanDefinition(beanName);
                        this.alreadyCreated.add(beanName);
                    }
                }
            }
        }          
    

    双重检查锁确保线程安全,Spring Boot中有多处使用双重检查锁的情况。

  2. 合并bean定义并处理@DeponsOn。

    //...
    try {
                    RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                    this.checkMergedBeanDefinition(mbd, beanName, args);
                    String[] dependsOn = mbd.getDependsOn();
                    String[] var11;
                    if (dependsOn != null) {
                        var11 = dependsOn;
                        int var12 = dependsOn.length;
    
                        for(int var13 = 0; var13 < var12; ++var13) {
                            String dep = var11[var13];
    						//...
                            this.registerDependentBean(dep, beanName);
    
                            try {
                                this.getBean(dep);
                            } //catch...
                        }
                    }
        //...
    

    Spring默认扫描包时会根据文件在文件夹位置先后顺序扫描,所以不能保证对象初始化顺序,方法或类上加上@DepondsOn后,会先初始化这个注解指定的对象。这里bean定义合并后,如果当前bean依赖了其他bean,被依赖bean中标注了@DepondsOn的先初始化,同样是用getBean方法。

  3. 不同域的bean的创建。


if (mbd.isSingleton()) {
        sharedInstance = this.getSingleton(beanName, () -> {
        try {
           return this.createBean(beanName, mbd, args);
        } //catch ...
        bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
      var11 = null;

       Object prototypeInstance;
       try {
           this.beforePrototypeCreation(beanName);
           prototypeInstance = this.createBean(beanName, mbd, args);
       } finally {
           this.afterPrototypeCreation(beanName);
       }

       bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
    //其他域的bean
    //...
}

根据当前bean的作用域创建对象,容器有两种域:单例sington和原型prototype,两种方式的底层都使用createBean。单例用getSingleton方法控制返回的引用唯一,原型每次会返回新的引用。每个分支最后同样对FactoryBean类型额外处理。

  1. getSingleton

    单例bean创建使用getSingleton方法,先从缓存中取,取到则返回,取不到就用它的第二个参数ObjectFactory的getObject方法返回单例对象,实际是用createBean创建的。

    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    
    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) {
                    //...
    
                    //控制循环依赖
                    this.beforeSingletonCreation(beanName);
                    boolean newSingleton = false;
    
                    try {
                        //缓存中取不到直接创建
                        singletonObject = singletonFactory.getObject();
                        newSingleton = true;
                    } //catch...
                    } finally {
                        this.afterSingletonCreation(beanName);
                    }
    
                	//创建好的bean放缓存
                    if (newSingleton) {
                        this.addSingleton(beanName, singletonObject);
                    }
                }
    
                return singletonObject;
            }
        }
    

    singletonFactory只是简单的函数式接口,singletonObject是createBean方法的执行结果。

    @FunctionalInterface
    public interface ObjectFactory<T> {
        T getObject() throws BeansException;
    }
    
11.3 createBean

两个处理点,通过resolveBeforeInstantiation创建对象和通过doCreateBean。

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        
        RootBeanDefinition mbdToUse = mbd;
        Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }
		//...

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if (beanInstance != null) {
                return beanInstance;
            }
        } // catch...

        try {
            beanInstance = this.doCreateBean(beanName, mbdToUse, args);
            
            return beanInstance;
        } // catch...
        
    }

resolveBeforeInstantiation分两步,先执行所有的InstantiationAwareBeanPostProcessor的初始化前逻辑生成对象,如果生成成功,就用所有的BeanPostProcessor的初始化后回调逻辑处理对象。

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = this.determineTargetType(beanName, mbd);
                if (targetType != null) {
                    //执行所有的InstantiationAwareBeanPostProcessor的初始化前回调逻辑生成bean
                    bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        //如果生成成功再执行初始化后回调
                        bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }

            mbd.beforeInstantiationResolved = bean != null;
        }

        return bean;
    }

如果resolveBeforeInstantiation没有创建出对象,需要用doCreateBean创建。

11.4 doCreateBean

doCreateBean方法执行3个逻辑:实列化bean、属性赋值和bean对象初始化。

11.4.1 实例化bean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws 		 BeanCreationException {
        BeanWrapper instanceWrapper = null;
        //...
        if (instanceWrapper == null) {
            //调createBeanInstance方法实例化bean
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }
    //...

​ 1. 先校验要创建的bean是否可访问:

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && 	!mbd.isNonPublicAccessAllowed()) {
            // throw ...
        }
  1. 再用工厂方法创建
			//...
			Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
            if (instanceSupplier != null) {
                return this.obtainFromSupplier(instanceSupplier, beanName);
            } else if (mbd.getFactoryMethodName() != null) {
                return this.instantiateUsingFactoryMethod(beanName, mbd, args);
            }

函数式接口Supplier可以完成bean对象创建,看一个案例:

先用@Component标注一个将要注册到容器中的bean。

package org.cosmos.springboot.induction.demo;

import org.springframework.stereotype.Component;

@Component
public class DemoBean {
    private String name;

    public DemoBean(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

再定义一个BeanFactoryPostProcessor用来提供创建bean的Supplier,Supplier可以自定义创建对象:

package org.cosmos.springboot.induction.demo;

@Component
public class SupplierBeanFactoryPostProcessor  implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        BeanDefinition demoBean = beanFactory.getBeanDefinition("demoBean");
        GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) demoBean;
        genericBeanDefinition.setInstanceSupplier(() -> new DemoBean("demo"));
        genericBeanDefinition.setBeanClass(DemoBean.class);
    }
}

执行主启动类的main:

package org.cosmos.springboot.induction.demo;

@SpringBootApplication
public class SpringBootInductionApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootInductionApplication.class, args);
    }
}

结果:

1-7.jpg

1-8.jpg

  1. 利用构造方法实例化bean。

基本流程是推断构造方法、构造方法参数注入、反射调构造方法创建对象。这里对于原型bean会在根bean定义中构造器参数,提高多次利用同一构造器创建对象的效率。

//...
else {
    			//构造器是否缓存
                boolean resolved = false;
    			//是否需要给构造方法参数注入值
    			//比如当前BeanDefinition用的是无参构造方法,那么autowireNecessary为false,否则为true
                boolean autowireNecessary = false;
                if (args == null) {
                    synchronized(mbd.constructorArgumentLock) {
                        if (mbd.resolvedConstructorOrFactoryMethod != null) {
                            resolved = true;
                            autowireNecessary = mbd.constructorArgumentsResolved;
                        }
                    }
                }

    			//构造器被缓存了
                if (resolved) {
                    //如果需要给构造方法参数注入值,就用缓存的参数注入构造器去实例化bean
                    //否则代表无参构造器,直接实例化
                    return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
                } else {
                    //构造器没被缓存,利用SmartInstantiationAwareBeanPostProcessor推断出构造器,这里也提供了一个扩展点
                    Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                    // 没有推断出且满足:配置的构造器自动注入参数方式不为AUTOWIRE_CONSTRUCTOR;
                    //且没通过Bean定义指定构造方法参数值;
                    //且调用getBean的时候没传入构造方法参数值
                    if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
                        //采用首选的构造器,使用了@Primary注解的为首选的
                        ctors = mbd.getPreferredConstructors();
                        //存在首选构造器,就去去实例化bean,否则用默认无参构造器实例bean
                        return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
                    } else {
                        //以上情况不满足(推断出了构造器,或构造器注入方式AUTOWIRE_CONSTRUCTOR,或bean定义指定了参数,或getBean时传进来了参数),则构造参数直接注入创建bean
                        return this.autowireConstructor(beanName, mbd, ctors, args);
                    }
                }
            }

到这里createBeanInstance实例化了bean,但没给属性赋值。

11.4.2 属性赋值前合并
//...
        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } // catch ...
                mbd.postProcessed = true;
            }
        }

applyMergedBeanDefinitionPostProcessors调容器中所有MergedBeanDefinitionPostProcessor,这里关注

InitDestroyAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor和AutowiredAnnotationBeanPostProcessor。

以InitDestroyAnnotationBeanPostProcessor为例观察下:

   public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
        InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = this.findLifecycleMetadata(beanType);
        metadata.checkConfigMembers(beanDefinition);
    }

findLifecycleMetadata会调buildLifecycleMetadata,会收集当前创建的bean中标注了@PostConstruct和@PreDestroy的方法:

    private InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata buildLifecycleMetadata(Class<?> clazz) {
      		//...
            List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> initMethods = new ArrayList();
            List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> destroyMethods = new ArrayList();
            Class targetClass = clazz;

            do {
                List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> currInitMethods = new ArrayList();
                List<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> currDestroyMethods = new ArrayList();
                //反射处理2种方法
                ReflectionUtils.doWithLocalMethods(targetClass, (method) -> {
                    if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                        InitDestroyAnnotationBeanPostProcessor.LifecycleElement element = new InitDestroyAnnotationBeanPostProcessor.LifecycleElement(method);
                        currInitMethods.add(element); 
                    }

                    if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                        currDestroyMethods.add(new InitDestroyAnnotationBeanPostProcessor.LifecycleElement(method)); 
                    }

                });
                //...
            } while(targetClass != null && targetClass != Object.class);

            //return ...
        }
    }

其他2种后置处理器逻辑大致相同,只是收集注解种类不同而已。

后面有对早期单例bean引用获取与缓存:

//...        
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if (earlySingletonExposure) {
            //与解决循环依赖有关
            this.addSingletonFactory(beanName, () -> {
                return this.getEarlyBeanReference(beanName, mbd, bean);
            });
        }
11.4.3 属性赋值populateBean
 try {
            this.populateBean(beanName, mbd, instanceWrapper);
            exposedObject = this.initializeBean(beanName, exposedObject, mbd);
        } //catch...

​ 看下populateBean的逻辑。

  1. 回调InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation逻辑。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
       		 //...
            if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator var4 = this.getBeanPostProcessors().iterator();

                while(var4.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var4.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            return;
                        }
                    }
                }
            }
  1. 回调InstantiationAwareBeanPostProcessor的postProcessProperties逻辑。
//...
 Iterator var9 = this.getBeanPostProcessors().iterator();
                while(var9.hasNext()) {
                    BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                        PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            //...
                            pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
                          //...
                        }
                       //...
                    }
                }

以CommonAnnotationBeanPostProcessor为例看下:

	public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
		InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
		try {
			metadata.inject(bean, beanName, pvs);
		} //catch ...
		return pvs;
	}

findResourceMetadata会调用buildResourceMetadata收集@Resource等。

	private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
		//...
		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

            //反射获取注解标注的字段
			ReflectionUtils.doWithLocalFields(targetClass, field -> {
				if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
					//判断...
					currElements.add(new WebServiceRefElement(field, field, null));
				}
				else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
					//判断...
					currElements.add(new EjbRefElement(field, field, null));
				}
				else if (field.isAnnotationPresent(Resource.class)) {
					//判断...
					if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
						currElements.add(new ResourceElement(field, field, null));
					}
				}
			});
			//反射获取注解标注的方法...
			
		}
		while (targetClass != null && targetClass != Object.class);

		// return ...
	}

收集好封装成元数据对象,然后用反射设置当前bean的属性值。

    public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectionMetadata.InjectedElement> checkedElements = this.checkedElements;
        //所有需要注入的信息
        Collection<InjectionMetadata.InjectedElement> elementsToIterate = checkedElements != null ? checkedElements : this.injectedElements;
        if (!((Collection)elementsToIterate).isEmpty()) {
            Iterator var6 = ((Collection)elementsToIterate).iterator();

            while(var6.hasNext()) {
                InjectionMetadata.InjectedElement element = (InjectionMetadata.InjectedElement)var6.next();
                //利用反射将需要注入到的其他bean对象设置成为当前创建bean的成员属性
                element.inject(target, beanName, pvs);
            }
        }
    }
  1. 属性赋值动作

    //...
     if (pvs != null) {
         //前面步骤生成的PropertyValues封装了当前bean的所有属性值,这里把它设置到bean中
          this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
      }
    
11.3.4 对象初始化initializeBean
    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        //if ...
        else {
            this.invokeAwareMethods(beanName, bean);
        }
        
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } // catch ...

        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }
  1. invokeAwareMethods:

    private void invokeAwareMethods(String beanName, Object bean) {
            if (bean instanceof Aware) {
                if (bean instanceof BeanNameAware) {
                    ((BeanNameAware)bean).setBeanName(beanName);
                }
    
                if (bean instanceof BeanClassLoaderAware) {
                    ClassLoader bcl = this.getBeanClassLoader();
                    if (bcl != null) {
                        ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
                    }
                }
    
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware)bean).setBeanFactory(this);
                }
            }
    
        }
    

    在prepareBeanFactory中,就注册一个ApplicationContextAwareProcessor,它的postProcessBeforeInitialization用来处理ApplicationContext有关的Aware接口。这里是其他几个Aware接口的处理。

  2. applyBeanPostProcessorsBeforeInitialization

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
            Object result = existingBean;
    
            Object current;
            for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
                BeanPostProcessor processor = (BeanPostProcessor)var4.next();
                current = processor.postProcessBeforeInitialization(result, beanName);
                if (current == null) {
                    return result;
                }
            }
    
            return result;
        }
    

    执行所有BeanPostProcessor的初始化前方法,包括上面说的ApplicationContextAwareProcessor设置ApplicationContxt到当前bean中,也包括InitDestroyAnnotationBeanPostProcessor回调bean中标注的@PostConstruct等方法。

    3.invokeInitMethods

    init-method和InitializingBean接口调用,我们最熟悉的实现InitializingBean接口并重写afterPropertiesSet方法就只是在这里被处理的:

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
            boolean isInitializingBean = bean instanceof InitializingBean;
            if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
               
    
                //if ...
                else {
                    ((InitializingBean)bean).afterPropertiesSet();
                }
            }
    
            if (mbd != null && bean.getClass() != NullBean.class) {
                String initMethodName = mbd.getInitMethodName();
                if (StringUtils.hasLength(initMethodName) && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
                    this.invokeCustomInitMethod(beanName, bean, mbd);
                }
            }
    
        }
    
    1. applyBeanPostProcessorsAfterInitialization:

          public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
              Object result = existingBean;
      
              Object current;
              for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
                  BeanPostProcessor processor = (BeanPostProcessor)var4.next();
                  current = processor.postProcessAfterInitialization(result, beanName);
                  if (current == null) {
                      return result;
                  }
              }
      
              return result;
          }
      

执行所有BeanPostProcessor的初始化后方法,如prepareBeanFactory中注册的ApplicationListenerDetector,它的初始化后方法会移除所有监听器。还要关注下AbstractAutoProxyCreator,和AOP有关,bean本身创建后根据需要创建代理对象:

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }

        return bean;
    }
}    

createBean中扩展点很多,我们来看下InstantiationAwareBeanPostProcessor,它继承了BeanPostProcessor,获得了父类的初始化前方法和初始化后方法,同时它本身又加了实例化前和实例化后以及属性注入前处理方法。Instantiation是实例化,Initialization是初始化。看一个案例:

1.DemoController类有2个属性:字符串creator,DemoService类型demoService,DemoController有一个无参构造:

package org.cosmos.springboot.induction.demo.processor;

@RestController
public class DemoController {
    private String creator = "c1";
    private DemoService demoService;

    public String getCreator() {
        return creator;
    }

    public void setCreator(String creator) {
        this.creator = creator;
        System.out.println("--DemoController内的creator被注入--");
    }


    @Autowired
    public void setDemoService(DemoService demoService) {
        this.demoService = demoService;
        System.out.println("--DemoController内的demoService被注入--");
    }

    public DemoController() {
        System.out.println("--DemoController无参构造被执行--");
    }
}

2.demoService:有一个无参构造

package org.cosmos.springboot.induction.demo.processor;

@Service
public class DemoService {
    public DemoService() {
        System.out.println("--DemoService无参构造被执行--");
    }

}

  1. 定义一个InstantiationAwareBeanPostProcessor,重写5个回调方法:

    package org.cosmos.springboot.induction.demo.processor;
    
    @Component
    public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
        //实例化前
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            if (beanName.equals("demoController")){
                System.out.println("--postProcessBeforeInstantiation被执行--");
            }
            return null;
        }
    
        //实例化后:这个方法返回后才能继续
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            if (beanName.equals("demoController")){
                System.out.println("--postProcessAfterInstantiation被执行--");
            }
            return true;
        }
    
        //属性注入前
        @Override
        public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
            if (beanName.equals("demoController")){
                System.out.println("--postProcessProperties被执行前--");
                MutablePropertyValues mutablePropertyValues = new MutablePropertyValues();
                mutablePropertyValues.addPropertyValue("creator", "c2");
                pvs = mutablePropertyValues;
            }
            return pvs;
        }
    
        //初始化前
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("demoController")){
                System.out.println("--postProcessBeforeInitialization--" + beanName);
            }
            return bean;
        }
    
        //初始化后
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            if (beanName.equals("demoController")){
                System.out.println("--postProcessAfterInitialization--" + beanName);
            }
            return bean;
        }
    }
    
    

    4.测试类:

    package org.cosmos.springboot.induction.demo.processor;
    
    public class Test {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext("org.cosmos.springboot.induction.demo.processor");
            DemoController bean = ctx.getBean(DemoController.class);
            System.out.println("----" + bean.getCreator());
        }
    }
    

    结果:

    1-11

1-11.jpg

分析:

​ AnnotationConfigApplicationContext构造方法参数传入要扫描的包路径,先调无参构造去初始化注解类定义读取器和类路径包扫描器,然后refresh去刷寻IOC容器:

	public AnnotationConfigApplicationContext(String... basePackages) {
		this();
		scan(basePackages);
		refresh();
	}

	public AnnotationConfigApplicationContext() {
		this.reader = new AnnotatedBeanDefinitionReader(this);
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

refresh执行到finishBeanFactoryInitialization时,先用getBean获取DemoController。

执行到createBean时先用resolveBeforeInstantiation创建对象,很明显本例中MyInstantiationAwareBeanPostProcessor的实例化前回调方法返回了null,所以它的实例化后方法也没回调,继续用doCreateBean创建对象。在实例化bean阶段,用构造方法创建了DemoController,日志也显示出来确实掉了DemoController的无参构造。bean实例化好后要属性赋值,先执行populateBean,这里会先回调InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,再回调它的的postProcessProperties。postProcessAfterInstantiation把DemoController的属性creator从"c1"设置成了"c2",同时要把demoService注入,这就触发了DemoService对象的创建。结果可以看到DemoService的无参构造接着执行了。demoService对象创建成功就会注入到DemoController,setter跟着执行,"c2"也被注入给creator。最后执行DemoController的初始化方法initializeBean,分别执行初始化前和初始化后方法。测试类最后执行getBean获取DemoController的creator属性证实了我们的干涉生效了。

这个案例说明了Spring Boot留给开发者的扩展点是非常有用的,我们可以在bean的生命周期中加上自定义逻辑。

所有懒加载单例bean全部初始化后,回到preInstantiateSingletons,最内层循环会处理所有实现了SmartInitializingSingleton的bean,回调它的afterSingletonsInstantiated。这也是提供出来的一个扩展点,作用和SpringApplication执行run方法提供的ApplicationRunner和CommandLineRunner类似。

12.finishRefresh:刷新后动作

	protected void finishRefresh() {
		//清除资源缓存
		clearResourceCaches();

		// Initialize lifecycle processor for this context.
        //初始化ApplicationContext的LifecycleProcessor
		initLifecycleProcessor();

		// 回调LifecycleProcessor
		getLifecycleProcessor().onRefresh();

		// 发布容器刷新完成事件
		publishEvent(new ContextRefreshedEvent(this));

		LiveBeansView.registerApplicationContext(this);
	}

所有非懒加载单例bean初始化后的动作,通过Lifecycle提供了一个新的切入点,可在容器启动和停止时触发它的start方法和stop方法。