Spring Boot 填充容器
Spring Boot填充容器
填充容器,即:自动装配Bean
第一步:通过
prepareRefresh()
方法,在已有的系统环境 **基础上,准备SERVLET相关的环境Environment,其他的环境在上篇第二大阶段环境准备** 中就已经注册完成了,通过初始化属性资源initServletPropertySources()
方法,对Servlet初始化参数servletContextInitParams
和servletConfigInitParams
进行赋值,1 2 3 4 5 6 7 8 9 10 11 12
public static void initServletPropertySources(MutablePropertySources sources, @Nullable ServletContext servletContext, @Nullable ServletConfig servletConfig) { Assert.notNull(sources, "'propertySources' must not be null"); String name = StandardServletEnvironment.SERVLET_CONTEXT_PROPERTY_SOURCE_NAME; if (servletContext != null && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletContextPropertySource(name, servletContext)); } name = StandardServletEnvironment.SERVLET_CONFIG_PROPERTY_SOURCE_NAME; if (servletConfig != null && sources.get(name) instanceof StubPropertySource) { sources.replace(name, new ServletConfigPropertySource(name, servletConfig)); } }
然后,通过
validateRequiredProperties()
检验是否有必要填充的环境变量,可以在自定义初始化属性资源initPropertySources()
方法中,1 2 3 4 5 6 7 8 9 10 11
public void validateRequiredProperties() { MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException(); for (String key: this.requiredProperties) { if (this.getProperty(key) == null) { ex.addMissingRequiredProperty(key); } } if (!ex.getMissingRequiredProperties().isEmpty()) { throw ex; } }
通过
setRequiredProperties()
将某些环境变量设置为必填1 2
// 把"MYSQL_HOST"作为启动时必须验证的环境变量 getEnvironment().setRequiredProperties("MYSQL_HOST");
最后,完成监听器和事件初始化之后,环境准备就完成了
第二三步:通过
obtainFreshBeanFactory()
和prepareBeanFactory()
方法,在获取容器同时在使用BeanFactory
之前进行一些准备工作,由于SpringBoot选择ServletWebServerApplicationContext
作为容器,之前步骤已经构建好beanFactiry
所以obatainFreshBeanFactory
中不进行任何处理,注意:在原始Spring中很多情况下会选择ClassPathXmlApplicationContext
作为容器,每次执行obtainFreshBeanFactory
时,会通过它的refreshBeanFactory()
方法重新构建beanFactory
并重新加载Bean定义 BeanDefinition,而是准备容器prepareBeanFactory
过程中,主要准备类加载器BeanClassLoader
,表达式解析器BeanExpressionResolver
、配置文件处理器PropertyEditorRegistrar
等系统处理器,以及两个Bean后置处理器;用来解析Aware
接口的ApplicationContextAwareProcessor
用来处理自定义监听器注册和销毁的ApplicationListenerDetector
同时会注册一些特殊Bean 和 系统级Bean 系统环境Environment
、系统属性SystemProperties
等,将它们放入特殊对象池 和 单例池 中1 2 3 4 5 6 7 8 9
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // Tell the internal bean factory to use the context's class loader etc. beanFactory.setBeanClassLoader(getClassLoader()); beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // Register early post-processor for detecting inner beans as ApplicationListeners. beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); }
第四步:通过
postProcessBeanFactory()
方法,对BeanFactory进行额外设置或修改,这里主要定义了包括request
、session
在内的Servlet相关作用域Scopes,同时也注册与Servlet相关的一些特殊Bean,包括:ServletRequest
、ServletResponse
、HttpSession
等;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { try { Properties mergedProps = mergeProperties(); // Convert the merged properties, if necessary. convertProperties(mergedProps); // Let the subclass process the properties. processProperties(beanFactory, mergedProps); }catch (IOException ex) { throw new BeanInitializationException("Could not load properties: " + ex.getMessage(), ex); } } public static void registerWebApplicationScopes(ConfigurableListableBeanFactory beanFactory,@Nullable ServletContext sc) { beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope()); beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope()); if (sc != null) { ServletContextScope appScope = new ServletContextScope(sc); beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, appScope); // Register as ServletContext attribute, for ContextCleanupListener to detect it. sc.setAttribute(ServletContextScope.class.getName(), appScope); } beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory()); beanFactory.registerResolvableDependency(ServletResponse.class, new ResponseObjectFactory()); beanFactory.registerResolvableDependency(HttpSession.class, new SessionObjectFactory()); beanFactory.registerResolvableDependency(WebRequest.class, new WebRequestObjectFactory()); if (jsfPresent) { FacesDependencyRegistrar.registerFacesDependencies(beanFactory); } }
第五步:开始执行非常核心的
invokeBeanFactoryPostProcessors()
方法,首先,逐一执行在第三个大阶段容器创建中,注册的各种BeanFactory后置处理器beanFactoryPostProcessor()
,其中最主要的就是用来加载所有Bean定义的配置处理器ConfigurationClassPostProcessor
通过它加载所有@Configuration
配置类,同时检索指定的Bean扫描路径componentScans
,然后通过Bean扫描器ClassPathBeanDefinitionScanner
中的doScan()
方法扫描每个类,将每个扫描出来的Bean定义都放到Bean定义池beanDefinitionMap
中,同样也会扫描所有加了@Bean、@Import
等注解的类和方法,将它们对应的Bean定义 也都放到 Bean定义池 中,这样后续就可以通过这些Bean定义构造相应的Bean对象。第六步:通过
registerBeanPostProcessors()
方法,检索所有的Bean后置处理器,同时根据指定的order
为它们进行排序,然后放入后置处理器BeanPostProcessor
中,每一个Bean后置处理器,都会在Bean初始化之前和之后分别执行对应的逻辑;1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. 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)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. List < BeanPostProcessor > orderedPostProcessors = new ArrayList < > (orderedPostProcessorNames.size()); for (String ppName: orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. 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); // Finally, re-register all internal BeanPostProcessors. sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
第七八步:通过
initMessageSource()
和initApplicationEventMulticaster()
方法,从单例池 中获取两个非常实用的Bean放在ApplicationContext中,一个是用于国际化,名为messageSource
的Bean,可以通过自定义名为MessageSource
的Bean,结合messages.properties
配置文件就可以进行多语言的切换配置1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource hms && hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. hms.setParentMessageSource(getInternalParentMessageSource()); } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { // Use empty MessageSource to be able to accept getMessage calls. DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace("No '" + MESSAGE_SOURCE_BEAN_NAME + "' bean, using [" + this.messageSource + "]"); } } }
另一个是用于自定义广播事件,名为
applicationEventMulticaster
的Bean,有了它就可以通过publishEvent()
方法进行事件的发布1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
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); if (logger.isTraceEnabled()) { logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " + "[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]"); } } }
第九步:需要通过
onRefresh
构造并启动Web服务器,先查找实现了ServletWebServerFactory
这个接口的应用服务器Bean,体内默认的服务器是Tomcat
,接下来通过getWebServer
方法构造一个Tomcat
对象,同时通过start()
方法进行启动,这样Web服务器就可以开始运行第十步:通过
registerListeners()
方法,在Bean中查找所有的监听器Bean,将它们注册到,第八步构造的消息广播器applicationEventMulticaster
中1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
protected void registerListeners() { // Register statically specified listeners first. for (ApplicationListener <? > listener: getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName: listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... Set < ApplicationEvent > earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (!CollectionUtils.isEmpty(earlyEventsToProcess)) { for (ApplicationEvent earlyEvent: earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
第十一步:这一步就是通过
finishBeanFactoryInitialization()
来生产所有的Bean,整体分为构造对象、填充属性、初始化实例、注册销毁四个步骤,可以参考Bean生命周期,Bean生成之后会放入单例池singletonObjects
中1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. 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)); } // Register a default embedded value resolver if no BeanFactoryPostProcessor // (such as a PropertySourcesPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal - > getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName: weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. beanFactory.preInstantiateSingletons(); }
第十二步:最后一步会通过
finishRefresh()
方法构造并注册生命周期管理器lifecycleProcessor
,同时会调用所有实现了生命周期接口Lifecycle
的Bean中的start()
方法,在容器关闭时也会自动调用对应的stop()
方法,接着发布一个容器刷新完成 的事件1 2 3 4 5 6 7 8 9 10 11 12 13
protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). clearResourceCaches(); // Initialize lifecycle processor for this context. initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. getLifecycleProcessor().onRefresh(); // Publish the final event. publishEvent(new ContextRefreshedEvent(this)); }