15、Spring~容器啟動過程
- 容器啟動過程
- AnnotationConfigApplicationContext類的四個構造器:
- 啟動過程詳解
- 無參構造方法
- refresh()方法
- prepareRefresh()方法
- prepareBeanFactory()方法
- invokeBeanFactoryPostProcessors()方法
- registerBeanPostProcessors()方法
- finishBeanFactoryInitialization()方法
- GenericApplicationContext對象詳解
- 構造方法
- DefaultListableBeanFactory對象詳解
- 構造方法
- preInstantiateSingletons()方法
- AnnotatedBeanDefinitionReader對象詳解
- 構造方法
- ConditionEvaluator對象
- 構造方法
- AnnotationConfigUtils對象
- registerAnnotationConfigProcessors()方法
- unwrapDefaultListableBeanFactory()方法
- ClassPathBeanDefinitionScanner對象
- 構造方法
- registerDefaultFilters()方法
- PostProcessorRegistrationDelegate對象
- invokeBeanFactoryPostProcessors()方法
- registerBeanPostProcessors()方法
- ConfigurationClassPostProcessor 對象
- postProcessBeanDefinitionRegistry()方法
容器啟動過程
??Spring容器的啟動過程,其實就是看AnnotationConfigApplicationContext對象或ClassPathXmlApplicationContext對象的創建過程,xml配置文件的使用方式不多,我們重點解析配置類的啟動方式,廢話不多說,上代碼,我們首先分析AnnotationConfigApplicationContext類的源碼
package org.springframework.context.annotation;import java.util.Arrays;
import java.util.function.Supplier;import org.springframework.beans.factory.config.BeanDefinitionCustomizer;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.metrics.StartupStep;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;/*** Standalone application context, accepting <em>component classes</em> as input —* in particular {@link Configuration @Configuration}-annotated classes, but also plain* {@link org.springframework.stereotype.Component @Component} types and JSR-330 compliant* classes using {@code javax.inject} annotations.** <p>Allows for registering classes one by one using {@link #register(Class...)}* as well as for classpath scanning using {@link #scan(String...)}.** <p>In case of multiple {@code @Configuration} classes, {@link Bean @Bean} methods* defined in later classes will override those defined in earlier classes. This can* be leveraged to deliberately override certain bean definitions via an extra* {@code @Configuration} class.** <p>See {@link Configuration @Configuration}'s javadoc for usage examples.** @author Juergen Hoeller* @author Chris Beams* @see #register* @see #scan* @see AnnotatedBeanDefinitionReader* @see ClassPathBeanDefinitionScanner* @see org.springframework.context.support.GenericXmlApplicationContext* @since 3.0*/
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {private final AnnotatedBeanDefinitionReader reader;private final ClassPathBeanDefinitionScanner scanner;/*** Create a new AnnotationConfigApplicationContext that needs to be populated* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.*/public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");// 額外會創建StandardEnvironmentthis.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();this.scanner = new ClassPathBeanDefinitionScanner(this);}/*** Create a new AnnotationConfigApplicationContext with the given DefaultListableBeanFactory.** @param beanFactory the DefaultListableBeanFactory instance to use for this context*/public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {super(beanFactory);this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);}/*** Create a new AnnotationConfigApplicationContext, deriving bean definitions* from the given component classes and automatically refreshing the context.** @param componentClasses one or more component classes — for example,* {@link Configuration @Configuration} classes*/public AnnotationConfigApplicationContext(Class<?>... componentClasses) {/*** this之前先調用父類GenericApplicationContext 的構造器,創建 DefaultListableBeanFactory* */// 構造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScannerthis();// 將啟動類注冊到BeanFactoryregister(componentClasses);// 刷新refresh();}/*** Create a new AnnotationConfigApplicationContext, scanning for components* in the given packages, registering bean definitions for those components,* and automatically refreshing the context.** @param basePackages the packages to scan for component classes*/public AnnotationConfigApplicationContext(String... basePackages) {this();scan(basePackages);refresh();}/*** Propagate the given custom {@code Environment} to the underlying* {@link AnnotatedBeanDefinitionReader} and {@link ClassPathBeanDefinitionScanner}.*/@Overridepublic void setEnvironment(ConfigurableEnvironment environment) {super.setEnvironment(environment);this.reader.setEnvironment(environment);this.scanner.setEnvironment(environment);}/*** Provide a custom {@link BeanNameGenerator} for use with {@link AnnotatedBeanDefinitionReader}* and/or {@link ClassPathBeanDefinitionScanner}, if any.* <p>Default is {@link AnnotationBeanNameGenerator}.* <p>Any call to this method must occur prior to calls to {@link #register(Class...)}* and/or {@link #scan(String...)}.** @see AnnotatedBeanDefinitionReader#setBeanNameGenerator* @see ClassPathBeanDefinitionScanner#setBeanNameGenerator* @see AnnotationBeanNameGenerator* @see FullyQualifiedAnnotationBeanNameGenerator*/public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) {this.reader.setBeanNameGenerator(beanNameGenerator);this.scanner.setBeanNameGenerator(beanNameGenerator);getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);}/*** Set the {@link ScopeMetadataResolver} to use for registered component classes.* <p>The default is an {@link AnnotationScopeMetadataResolver}.* <p>Any call to this method must occur prior to calls to {@link #register(Class...)}* and/or {@link #scan(String...)}.*/public void setScopeMetadataResolver(ScopeMetadataResolver scopeMetadataResolver) {this.reader.setScopeMetadataResolver(scopeMetadataResolver);this.scanner.setScopeMetadataResolver(scopeMetadataResolver);}//---------------------------------------------------------------------// Implementation of AnnotationConfigRegistry//---------------------------------------------------------------------/*** Register one or more component classes to be processed.* <p>Note that {@link #refresh()} must be called in order for the context* to fully process the new classes.** @param componentClasses one or more component classes — for example,* {@link Configuration @Configuration} classes* @see #scan(String...)* @see #refresh()*/@Overridepublic void register(Class<?>... componentClasses) {Assert.notEmpty(componentClasses, "At least one component class must be specified");StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register").tag("classes", () -> Arrays.toString(componentClasses));this.reader.register(componentClasses);registerComponentClass.end();}/*** Perform a scan within the specified base packages.* <p>Note that {@link #refresh()} must be called in order for the context* to fully process the new classes.** @param basePackages the packages to scan for component classes* @see #register(Class...)* @see #refresh()*/@Overridepublic void scan(String... basePackages) {Assert.notEmpty(basePackages, "At least one base package must be specified");StartupStep scanPackages = this.getApplicationStartup().start("spring.context.base-packages.scan").tag("packages", () -> Arrays.toString(basePackages));this.scanner.scan(basePackages);scanPackages.end();}//---------------------------------------------------------------------// Adapt superclass registerBean calls to AnnotatedBeanDefinitionReader//---------------------------------------------------------------------@Overridepublic <T> void registerBean(@Nullable String beanName, Class<T> beanClass,@Nullable Supplier<T> supplier, BeanDefinitionCustomizer... customizers) {this.reader.registerBean(beanClass, beanName, supplier, customizers);}}
通過上述類上的注釋,我們大概了解到這是一個Spring的上下文,可以接受添加@Configuration注解的類當成參數,也可以接受一個添加@Component注解的普通Bean當成參數;
AnnotationConfigApplicationContext類的四個構造器:
// 無參構造器
public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");this.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();this.scanner = new ClassPathBeanDefinitionScanner(this);
}// 參數是DefaultListableBeanFactory 的構造器
public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {super(beanFactory);this.reader = new AnnotatedBeanDefinitionReader(this);this.scanner = new ClassPathBeanDefinitionScanner(this);
}// 參數是Class文件的構造器
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {this();register(componentClasses);refresh();
}// 參數是掃描路徑的構造器
public AnnotationConfigApplicationContext(String... basePackages) {this();scan(basePackages);refresh();
}
啟動過程詳解
這里我們重點分析使用最多的:參數是Class文件的構造器
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {// this之前先調用父類GenericApplicationContext 的構造器,創建 DefaultListableBeanFactory// 構造DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScannerthis();// 將啟動類注冊到BeanFactoryregister(componentClasses);// 刷新refresh();}
這里我們可以看到:
- 首先會調用無參構造
- 調用register()方法將配置類注冊到BeanFactory中;
- 調用refresh()方法,刷新Spring容器;
無參構造方法
無參構造方法詳解
/*** Create a new AnnotationConfigApplicationContext that needs to be populated* through {@link #register} calls and then manually {@linkplain #refresh refreshed}.*/
public AnnotationConfigApplicationContext() {StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");// 額外會創建StandardEnvironmentthis.reader = new AnnotatedBeanDefinitionReader(this);createAnnotatedBeanDefReader.end();this.scanner = new ClassPathBeanDefinitionScanner(this);
}
通過上述代碼,我們可以看到:
- AnnotationConfigApplicationContext類在調用無參構造方法之前,會先調用父類的無參構造方法,也就是GenericApplicationContext類的無參構造方法,我們先看一下GenericApplicationContext類在構造方法中做啦什么;
- 通過對GenericApplicationContext類的分析,發現主要就是創建啦beanFactory;
- 然后我們再看AnnotationConfigApplicationContext類自己的無參構造器;
- 首先會創建AnnotatedBeanDefinitionReader對象(BeanDefinition讀取器:詳情請移步至《Spring之底層架構核心概念》)
- 再往下創建ClassPathBeanDefinitionScanner掃描器;
返回啟動過程詳解;
refresh()方法
refresh()方法詳解
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");// Prepare this context for refreshing./*** 準備刷新;* 設置一些初始值、環境變量之類操作* */prepareRefresh();// Tell the subclass to refresh the internal bean factory.// 這里會判斷能否刷新,并且返回一個BeanFactory, 刷新不代表完全情況,主要是先執行Bean的銷毀,然后重新生成一個BeanFactory,再在接下來的步驟中重新去掃描等等/*** 給BeanFactory設置一個序列化id* 將創建好的BeanFactory對象返回* */ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.// 準備BeanFactory// 1. 設置BeanFactory的類加載器、SpringEL表達式解析器、類型轉化注冊器// 2. 添加三個BeanPostProcessor,注意是具體的BeanPostProcessor實例對象// 3. 記錄ignoreDependencyInterface// 4. 記錄ResolvableDependency// 5. 添加三個單例BeanprepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.// 子類來設置一下BeanFactorypostProcessBeanFactory(beanFactory);StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");// Invoke factory processors registered as beans in the context.// BeanFactory準備好了之后,執行BeanFactoryPostProcessor,開始對BeanFactory進行處理// 默認情況下:// 此時beanFactory的beanDefinitionMap中有6個BeanDefinition,5個基礎BeanDefinition+AppConfig的BeanDefinition// 而這6個中只有一個BeanFactoryPostProcessor:ConfigurationClassPostProcessor// 這里會執行ConfigurationClassPostProcessor進行@Component的掃描,掃描得到BeanDefinition,并注冊到beanFactory中// 注意:掃描的過程中可能又會掃描出其他的BeanFactoryPostProcessor,那么這些BeanFactoryPostProcessor也得在這一步執行//處理 BeanFactoryPostProcessorinvokeBeanFactoryPostProcessors(beanFactory); // scanner.scan()// Register bean processors that intercept bean creation.// 將掃描到的BeanPostProcessors實例化并排序,并添加到BeanFactory的beanPostProcessors屬性中去//處理 BeanPostProcessorsregisterBeanPostProcessors(beanFactory);beanPostProcess.end();// Initialize message source for this context.// 設置ApplicationContext的MessageSource,要么是用戶設置的,要么是DelegatingMessageSource// 設置國際化initMessageSource();// Initialize event multicaster for this context.// 設置ApplicationContext的applicationEventMulticaster,要么是用戶設置的,要么是SimpleApplicationEventMulticaster//設置事件發布器initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.// 給子類的模板方法onRefresh();// Check for listener beans and register them.// 把定義的ApplicationListener的Bean對象,設置到ApplicationContext中去,并執行在此之前所發布的事件//設置 事件監聽器registerListeners();// Instantiate all remaining (non-lazy-init) singletons.// 完成 bean工廠 初始化finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();} catch (BeansException ex) {if (logger.isWarnEnabled()) {logger.warn("Exception encountered during context initialization - " +"cancelling refresh attempt: " + ex);}// Destroy already created singletons to avoid dangling resources.destroyBeans();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;} finally {// Reset common introspection caches in Spring's core, since we// might not ever need metadata for singleton beans anymore...resetCommonCaches();contextRefresh.end();}}
}
通過上述代碼,我們可以看到:
- 調用prepareRefresh()方法,設置一些初始值、環境變量之類操作;
- 調用obtainFreshBeanFactory()方法,獲取給BeanFactory設置一個序列化id,并拿到BeanFactory對象;
- 調用prepareBeanFactory()方法;
- 調用postProcessBeanFactory()方法,給子類來設置一下BeanFactory,SpringMVC會有相關設置,Spring容器是一個空方法;
- 調用invokeBeanFactoryPostProcessors()方法,執行BeanFactory的后置處理;
- 調用registerBeanPostProcessors()方法,方法名直譯就是,注冊BeanPostProcessors
- 調用initMessageSource()方法,設置國際化;
- 調用initApplicationEventMulticaster()方法,設置時間發布器;
- onRefresh()方法是給子類的模板方法,SpringMVC會用到;
- 調用registerListeners()方法,設置事件監聽器;
- 調用finishBeanFactoryInitialization()方法,完成bean工廠初始化;
- 到這里Spring容器啟動成功;
返回啟動過程詳解;
prepareRefresh()方法
prepareRefresh()方法詳解
/*** Prepare this context for refreshing, setting its startup date and* active flag as well as performing any initialization of property sources.*/
protected void prepareRefresh() {// Switch to active.this.startupDate = System.currentTimeMillis();this.closed.set(false);this.active.set(true);if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing " + this);} else {logger.debug("Refreshing " + getDisplayName());}}// Initialize any placeholder property sources in the context environment.// 比如子類可以把ServletContext中的參數對設置到EnvironmentinitPropertySources();// Validate that all properties marked as required are resolvable:// see ConfigurablePropertyResolver#setRequiredPropertiesgetEnvironment().validateRequiredProperties();// Store pre-refresh ApplicationListeners...if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);} else {// Reset local application listeners to pre-refresh state.this.applicationListeners.clear();this.applicationListeners.addAll(this.earlyApplicationListeners);}// Allow for the collection of early ApplicationEvents,// to be published once the multicaster is available...this.earlyApplicationEvents = new LinkedHashSet<>();
}
這里沒什么有營養代碼和知識,自行閱讀即可;
返回refresh()方法;
prepareBeanFactory()方法
prepareBeanFactory()方法詳解
/*** Configure the factory's standard context characteristics,* such as the context's ClassLoader and post-processors.** @param beanFactory the BeanFactory to configure*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// Tell the internal bean factory to use the context's class loader etc.// 獲取類加載器設置給beanFactory,如果前面設置啦類加載器就用設置好的,沒設置就用默認的AppClassLoader,beanFactory.setBeanClassLoader(getClassLoader());// Spring5.3中新增的功能,可以選擇是否開啟Spel功能,shouldIgnoreSpel默認為false,表示開啟if (!shouldIgnoreSpel) {// 將spring表達式設置給beanFactorybeanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}// 添加一個ResourceEditorRegistrar,注冊一些默認的類型轉化器beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// Configure the bean factory with context callbacks.// 添加一個BeanPostProcessor,用來處理EnvironmentAware、EmbeddedValueResolverAware等回調beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 如果一個屬性對應的set方法在ignoredDependencyInterfaces接口中被定義了,則該屬性不會進行自動注入(是Spring中的自動注入,不是@Autowired)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.ignoreDependencyInterface(ApplicationStartupAware.class);// BeanFactory interface not registered as resolvable type in a plain factory.// MessageSource registered (and found for autowiring) as a bean.beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);beanFactory.registerResolvableDependency(ResourceLoader.class, this);beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);beanFactory.registerResolvableDependency(ApplicationContext.class, this);// Register early post-processor for detecting inner beans as ApplicationListeners.// ApplicationListenerDetector負責把ApplicantsListener類型的Bean注冊到ApplicationContext中beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// Detect a LoadTimeWeaver and prepare for weaving, if found.// Aspectj本身是通過編譯期進行代理的,在Spring中就跟LoadTimeWeaver有關if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// Set a temporary ClassLoader for type matching.beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}/*** 將環境變量和Application啟動類放入單例池中* */// Register default environment beans.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());}if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}
}
通過上述代碼,我們可以看到:
- 首先會給BeanFactory設置類加載器;
- 如果shouldIgnoreSpel是false,給BeanFactory設置Spring表達式解析器,shouldIgnoreSpel默認是false;
- 再往下,給BeanFactory添加一個ResourceEditorRegistrar,注冊一些默認的類型轉化器;
- 再往下,添加一個ApplicationContextAwareProcessor,用來處理EnvironmentAware、EmbeddedValueResolverAware等回調;
- 將EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware、ApplicationStartupAware添加到BeanFactory的ignoredDependencyInterfaces集合中,表示這個幾個接口的實現類不會執行spring自帶的自動注入@Bean(autowire = Autowire.BY_TYPE),如果實現類有@Autowired、@Inject、@Value、@Resource四個注解還是會執行自動注入;
- 將BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext添加到存儲類型和對象對應信息的resolvableDependencies中;
- 將負責事件監聽的ApplicationListenerDetector添加到BeanFactory中的BeanPostProcessor集合中,ApplicationListenerDetector雖然從命名上看不出和BeanPostProcessor的關系,其實他實現啦DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor兩個接口;
- 在往下這個判斷是和Aspectj有關;
- 最后,將環境變量和Application啟動類放入單例池中;
返回refresh()方法;
invokeBeanFactoryPostProcessors()方法
invokeBeanFactoryPostProcessors()方法詳解
/*** Instantiate and invoke all registered BeanFactoryPostProcessor beans,* respecting explicit order if given.* <p>Must be called before singleton instantiation.*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {// 重點PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)// 關于LoadTimeWeaver看這篇文章了解即可,https://www.cnblogs.com/wade-luffy/p/6073702.htmlif (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}
}
通過上述代碼,我們可以看到:
- 首先調用PostProcessorRegistrationDelegate類的invokeBeanFactoryPostProcessors()方法;
- 下面這個判斷和LoadTimeWeaver相關,這里不展開細說;
返回refresh()方法;
registerBeanPostProcessors()方法
registerBeanPostProcessors()方法詳解
/*** Instantiate and register all BeanPostProcessor beans,* respecting explicit order if given.* <p>Must be called before any instantiation of application beans.*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
??通過上述代碼,我們可以看到,這里會調用PostProcessorRegistrationDelegate類的registerBeanPostProcessors()方法,我們詳細分析PostProcessorRegistrationDelegate類的registerBeanPostProcessors()方法;
返回refresh()方法;
finishBeanFactoryInitialization()方法
finishBeanFactoryInitialization()方法詳解
/*** Finish the initialization of this context's bean factory,* initializing all remaining singleton beans.*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {// Initialize conversion service for this context.// 如果BeanFactory中存在名字叫conversionService的Bean,則設置為BeanFactory的conversionService屬性// 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));}// 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.// 設置默認的占位符解析器 ${xxx} ---keyif (!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.// 實例化非懶加載的單例BeanbeanFactory.preInstantiateSingletons();
}
通過上述代碼,我們可以看到:
- 首先判斷,如果BeanFactory中存在名字叫conversionService的Bean,則設置為BeanFactory的conversionService屬性,ConversionService是用來進行類型轉化的;
- 設置占位符解析器;
- 實例化實現LoadTimeWeaverAware接口的Bean對象;
- 調用preInstantiateSingletons()方法,實例化非懶加載的單例Bean;
返回refresh()方法;
GenericApplicationContext對象詳解
構造方法
GenericApplicationContext對象構造方法詳解
/*** Create a new GenericApplicationContext.* @see #registerBeanDefinition* @see #refresh*/
public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();
}
GenericApplicationContext對象的無參構造方法也簡單,就是創建beanFactory,我們再看一下這個DefaultListableBeanFactory都做啦什么;
返回AnnotationConfigApplicationContext類的無參構造方法
DefaultListableBeanFactory對象詳解
構造方法
DefaultListableBeanFactory的構造方法詳解
/*** Create a new DefaultListableBeanFactory.*/
public DefaultListableBeanFactory() {super();
}
這里我們可以看到,DefaultListableBeanFactory類在構造方法中什么都沒干,只是調用父類的構造方法,我們再看一下他父類的構造方法:
/*** Create a new AbstractAutowireCapableBeanFactory.*/
public AbstractAutowireCapableBeanFactory() {super();/*** 將 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware 添加到* ignoredDependencyInterfaces屬性中,表示自動注入時會忽略所有* 實現 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口的類* */ignoreDependencyInterface(BeanNameAware.class);ignoreDependencyInterface(BeanFactoryAware.class);ignoreDependencyInterface(BeanClassLoaderAware.class);if (NativeDetector.inNativeImage()) {this.instantiationStrategy = new SimpleInstantiationStrategy();} else {this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();}
}
AbstractAutowireCapableBeanFactory類(DefaultListableBeanFactory的父類)在構造方法中我們可以看到:
- 同樣先調用父類構造方法,在AbstractBeanFactory類(AbstractAutowireCapableBeanFactory的父類)的構造方法中什么都沒做;
- 然后依次調用ignoreDependencyInterface()方法,將 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware 添加到ignoredDependencyInterfaces屬性中,表示自動注入時會忽略所有實現 BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口的類;
- 再往下,NativeDetector.inNativeImage(),這個判斷是判斷我們是否使用graalvm;
- 一般情況我肯定是false,然后創建Cglib的實例化策略;
返回GenericApplicationContext類;
preInstantiateSingletons()方法
preInstantiateSingletons()方法詳解
@Override
public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {// 獲取合并后的BeanDefinitionRootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {// 獲取FactoryBean對象Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,getAccessControlContext());} else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {// 創建真正的Bean對象(getObject()返回的對象)getBean(beanName);}}} else {// 創建Bean對象getBean(beanName);}}}System.out.println("=====調用SmartInitializingSingleton接口的afterSingletonsInstantiated方法=====");// 所有的非懶加載單例Bean都創建完了后// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize").tag("beanName", beanName);SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();return null;}, getAccessControlContext());} else {smartSingleton.afterSingletonsInstantiated();}smartInitialize.end();}}
}
此方法詳情,請移步至《Spring之Bean生命周期~合并BeanDefinition》;
返回finishBeanFactoryInitialization()方法;
AnnotatedBeanDefinitionReader對象詳解
構造方法
AnnotatedBeanDefinitionReader對象構造方法詳解
/*** Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.* <p>If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},* the {@link Environment} will be inherited, otherwise a new* {@link StandardEnvironment} will be created and used.** @param registry the {@code BeanFactory} to load bean definitions into,* in the form of a {@code BeanDefinitionRegistry}* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)* @see #setEnvironment(Environment)*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {// getOrCreateEnvironment方法 創建環境變量this(registry, getOrCreateEnvironment(registry));
}/*** Create a new {@code AnnotatedBeanDefinitionReader} for the given registry,* using the given {@link Environment}.** @param registry the {@code BeanFactory} to load bean definitions into,* in the form of a {@code BeanDefinitionRegistry}* @param environment the {@code Environment} to use when evaluating bean definition* profiles.* @since 3.1*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");Assert.notNull(environment, "Environment must not be null");this.registry = registry;// 用來解析@Conditional(條件注解)注解的this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);// 注冊AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
通過上述代碼,我們可以看到:
- AnnotationConfigApplicationContext的無參構造器在創建AnnotatedBeanDefinitionReader對象時,是通過無參構造器創建的;
- 無參構造方法先調用getOrCreateEnvironment()方法獲取到環境變量;
- 然后又調用啦有參構造器;
- 首先通過ConditionEvaluator的有參構造方法創建ConditionEvaluator對象(用來解析@Conditional(條件注解)注解的);
- 調用AnnotationConfigUtils類的registerAnnotationConfigProcessors()方法,注冊我么后續用到的一些AnnotationAwareOrderComparator比較器、ContextAnnotationAutowireCandidateResolver候選解析器和一些后置處理器;
返回AnnotationConfigApplicationContext類的無參構造方法
ConditionEvaluator對象
構造方法
ConditionEvaluator對象構造方法詳解
/*** Create a new {@link ConditionEvaluator} instance.*/
public ConditionEvaluator(@Nullable BeanDefinitionRegistry registry,@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {this.context = new ConditionContextImpl(registry, environment, resourceLoader);
}
??這里我們可以看到ConditionEvaluator在構造方法中創建啦ConditionContextImpl對象,而ConditionContextImpl對象是ConditionEvaluator的靜態內部類,我們再分析ConditionContextImpl這個靜態內部類;
public ConditionContextImpl(@Nullable BeanDefinitionRegistry registry,@Nullable Environment environment, @Nullable ResourceLoader resourceLoader) {this.registry = registry;this.beanFactory = deduceBeanFactory(registry);this.environment = (environment != null ? environment : deduceEnvironment(registry));this.resourceLoader = (resourceLoader != null ? resourceLoader : deduceResourceLoader(registry));this.classLoader = deduceClassLoader(resourceLoader, this.beanFactory);
}
通過上述代碼我們可以看到;
- 首先設置registry 屬性,registry 屬性是我們一開始傳進來的AnnotationConfigApplicationContext對象(Spring容器);
- 然后調用deduceBeanFactory()方法獲取BeanFactory;
- 獲取environment (環境變量);
- 設置resourceLoader (資源讀取器);
- 設置classLoader (類加載器);
返回AnnotatedBeanDefinitionReader對象詳解
AnnotationConfigUtils對象
registerAnnotationConfigProcessors()方法
registerAnnotationConfigProcessors()方法詳解
/*** Register all relevant annotation post processors in the given registry.** @param registry the registry to operate on*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {registerAnnotationConfigProcessors(registry, null);
}/*** Register all relevant annotation post processors in the given registry.** @param registry the registry to operate on* @param source the configuration source element (already extracted)* that this registration was triggered from. May be {@code null}.* @return a Set of BeanDefinitionHolders, containing all bean definitions* that have actually been registered by this call*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, @Nullable Object source) {DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);if (beanFactory != null) {// 設置beanFactory的OrderComparator為AnnotationAwareOrderComparator// 它是一個Comparator,是一個比較器,可以用來進行排序,比如new ArrayList<>().sort(Comparator);if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);}// 用來判斷某個Bean能不能用來進行依賴注入if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());}}Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);// 注冊ConfigurationClassPostProcessor類型的BeanDefinitionif (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注冊AutowiredAnnotationBeanPostProcessor類型的BeanDefinitionif (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注冊CommonAnnotationBeanPostProcessor類型的BeanDefinition// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注冊PersistenceAnnotationBeanPostProcessor類型的BeanDefinition// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition();try {def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,AnnotationConfigUtils.class.getClassLoader()));} catch (ClassNotFoundException ex) {throw new IllegalStateException("Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);}def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));}// 注冊EventListenerMethodProcessor類型的BeanDefinition,用來處理@EventListener注解的if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));}// 注冊DefaultEventListenerFactory類型的BeanDefinition,用來處理@EventListener注解的if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);def.setSource(source);beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));}return beanDefs;
}
??通過上述代碼我們可以看到,registerAnnotationConfigProcessors方法有一個重載方法,接下來我們詳細分析registerAnnotationConfigProcessors方法中的處理邏輯:
- 調用unwrapDefaultListableBeanFactory()方法獲取beanFactory;
- 再往下,如果beanFactory沒有設置AnnotationAwareOrderComparator比較器的話,設置一下AnnotationAwareOrderComparator比較器,AnnotationAwareOrderComparator比較器的作用:可以根據@Priority注解、Ordered接口和@Order注解設置的值進行排序;
- 再往下,如果beanFactory沒有設置ContextAnnotationAutowireCandidateResolver候選解析器的話,設置一下ContextAnnotationAutowireCandidateResolver候選解析器,ContextAnnotationAutowireCandidateResolver候選解析器的作用:判斷某個bean針對當前依賴是否能注入;比如@Bean注解中autowireCandidate屬性設置成false是不能注入給其他bean的;
- 再往下,將ConfigurationClassPostProcessor設置成BeanDefinition,并添加到beanDefs中;(ConfigurationClassPostProcessorl類的postProcessBeanDefinitionRegistry方法會解析配置類,觸發掃描);
- 再往下,將AutowiredAnnotationBeanPostProcessor設置成BeanDefinition,并添加到beanDefs中;AutowiredAnnotationBeanPostProcessor的作用:會掃描@Autowired、@Value、@Inject注入點,對注入點進行依賴注入,詳情請移步至《Spring之Bean生命周期~依賴注入(2)》
- 再往下,將CommonAnnotationBeanPostProcessor設置成BeanDefinition,并添加到beanDefs中;CommonAnnotationBeanPostProcessor的作用:會掃描@Resource注入點,對注入點進行依賴注入,詳情請移步至《Spring之Bean生命周期~依賴注入(3)》;
- 再往下,如果是JPA會注冊PersistenceAnnotationBeanPostProcessor,沒有JPA不會進入判斷;
- 再往下,依次將EventListenerMethodProcessor和DefaultEventListenerFactory設置成BeanDefinition,并添加到beanDefs中;EventListenerMethodProcessor和DefaultEventListenerFactory的作用:處理@EventListener注解的;
返回AnnotatedBeanDefinitionReader對象;
unwrapDefaultListableBeanFactory()方法
unwrapDefaultListableBeanFactory()方法詳解
@Nullable
private static DefaultListableBeanFactory unwrapDefaultListableBeanFactory(BeanDefinitionRegistry registry) {if (registry instanceof DefaultListableBeanFactory) {return (DefaultListableBeanFactory) registry;} else if (registry instanceof GenericApplicationContext) {return ((GenericApplicationContext) registry).getDefaultListableBeanFactory();} else {return null;}
}
??通過上述代碼,我們可以看到這里主要是獲取BeanFactory對象,因為我們之前是通過GenericApplicationContext創建的BeanFactory,所以合理會走GenericApplicationContext類的getDefaultListableBeanFactory()方法拿到之前創建好的BeanFactory對象;
返回registerAnnotationConfigProcessors()方法
ClassPathBeanDefinitionScanner對象
構造方法
ClassPathBeanDefinitionScanner構造方法詳解
/*** Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory.** @param registry the {@code BeanFactory} to load bean definitions into, in the form* of a {@code BeanDefinitionRegistry}*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {this(registry, true);
}/*** Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory.* <p>If the passed-in bean factory does not only implement the* {@code BeanDefinitionRegistry} interface but also the {@code ResourceLoader}* interface, it will be used as default {@code ResourceLoader} as well. This will* usually be the case for {@link org.springframework.context.ApplicationContext}* implementations.* <p>If given a plain {@code BeanDefinitionRegistry}, the default {@code ResourceLoader}* will be a {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.* <p>If the passed-in bean factory also implements {@link EnvironmentCapable} its* environment will be used by this reader. Otherwise, the reader will initialize and* use a {@link org.springframework.core.env.StandardEnvironment}. All* {@code ApplicationContext} implementations are {@code EnvironmentCapable}, while* normal {@code BeanFactory} implementations are not.** @param registry the {@code BeanFactory} to load bean definitions into, in the form* of a {@code BeanDefinitionRegistry}* @param useDefaultFilters whether to include the default filters for the* {@link org.springframework.stereotype.Component @Component},* {@link org.springframework.stereotype.Repository @Repository},* {@link org.springframework.stereotype.Service @Service}, and* {@link org.springframework.stereotype.Controller @Controller} stereotype annotations* @see #setResourceLoader* @see #setEnvironment*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}/*** Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory and* using the given {@link Environment} when evaluating bean definition profile metadata.* <p>If the passed-in bean factory does not only implement the {@code* BeanDefinitionRegistry} interface but also the {@link ResourceLoader} interface, it* will be used as default {@code ResourceLoader} as well. This will usually be the* case for {@link org.springframework.context.ApplicationContext} implementations.* <p>If given a plain {@code BeanDefinitionRegistry}, the default {@code ResourceLoader}* will be a {@link org.springframework.core.io.support.PathMatchingResourcePatternResolver}.** @param registry the {@code BeanFactory} to load bean definitions into, in the form* of a {@code BeanDefinitionRegistry}* @param useDefaultFilters whether to include the default filters for the* {@link org.springframework.stereotype.Component @Component},* {@link org.springframework.stereotype.Repository @Repository},* {@link org.springframework.stereotype.Service @Service}, and* {@link org.springframework.stereotype.Controller @Controller} stereotype annotations* @param environment the Spring {@link Environment} to use when evaluating bean* definition profile metadata* @see #setResourceLoader* @since 3.1*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment) {this(registry, useDefaultFilters, environment,(registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}/*** Create a new {@code ClassPathBeanDefinitionScanner} for the given bean factory and* using the given {@link Environment} when evaluating bean definition profile metadata.** @param registry the {@code BeanFactory} to load bean definitions into, in the form* of a {@code BeanDefinitionRegistry}* @param useDefaultFilters whether to include the default filters for the* {@link org.springframework.stereotype.Component @Component},* {@link org.springframework.stereotype.Repository @Repository},* {@link org.springframework.stereotype.Service @Service}, and* {@link org.springframework.stereotype.Controller @Controller} stereotype annotations* @param environment the Spring {@link Environment} to use when evaluating bean* definition profile metadata* @param resourceLoader the {@link ResourceLoader} to use* @since 4.3.6*/
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,Environment environment, @Nullable ResourceLoader resourceLoader) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");this.registry = registry;if (useDefaultFilters) {registerDefaultFilters();}setEnvironment(environment);setResourceLoader(resourceLoader);
}
通過上述代碼跟蹤,最終調到啦參數最多的構造器,我們詳細分析參數最多的構造方法:
- 一個參數構造器調用兩個參數構造器時,手動設置啦useDefaultFilters是true;
- 調用registerDefaultFilters()方法,將@Component注解添加到includeFilters過濾器中;
- 設置環境變量和資源加載器;
返回AnnotationConfigApplicationContext的無參構造方法
registerDefaultFilters()方法
registerDefaultFilters()方法詳解
/*** Register the default filter for {@link Component @Component}.* <p>This will implicitly register all annotations that have the* {@link Component @Component} meta-annotation including the* {@link Repository @Repository}, {@link Service @Service}, and* {@link Controller @Controller} stereotype annotations.* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and* JSR-330's {@link javax.inject.Named} annotations, if available.*/
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {// 注冊@Component對應的AnnotationTypeFilterthis.includeFilters.add(new AnnotationTypeFilter(Component.class));ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");} catch (ClassNotFoundException ex) {// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.}try {this.includeFilters.add(new AnnotationTypeFilter(((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");} catch (ClassNotFoundException ex) {// JSR-330 API not available - simply skip.}
}
通過上述代碼,我們可以看到:
- 首先將@Component注解添加到includeFilters過濾器中;
- 接下來是添加@ManagedBean注解和@Named注解,這兩個都是java自帶注解,使用不多,不展開細講;
返回ClassPathBeanDefinitionScanner類的構造方法
PostProcessorRegistrationDelegate對象
invokeBeanFactoryPostProcessors()方法
invokeBeanFactoryPostProcessors()方法詳解
/*** BeanFactoryPostProcessors按入場方式分為:* 1. 程序員調用ApplicationContext的API手動添加* 2. Spring自己掃描出來的* <p>* BeanFactoryPostProcessor按類型又可以分為:* 1. 普通BeanFactoryPostProcessor* 2. BeanDefinitionRegistryPostProcessor* <p>* 執行順序順序如下:* 1. 執行手動添加的BeanDefinitionRegistryPostProcessor 的postProcessBeanDefinitionRegistry()方法* 2. 執行掃描出來的BeanDefinitionRegistryPostProcessor(實現了PriorityOrdered)的postProcessBeanDefinitionRegistry()方法* 3. 執行掃描出來的BeanDefinitionRegistryPostProcessor(實現了Ordered) 的postProcessBeanDefinitionRegistry()方法* 4. 執行掃描出來的BeanDefinitionRegistryPostProcessor(普通) 的postProcessBeanDefinitionRegistry()方法* 5. 執行掃描出來的BeanDefinitionRegistryPostProcessor(所有) 的postProcessBeanFactory()方法* 6. 執行手動添加的BeanFactoryPostProcessor 的postProcessBeanFactory()方法* 7. 執行掃描出來的BeanFactoryPostProcessor(實現了PriorityOrdered) 的postProcessBeanFactory()方法* 8. 執行掃描出來的BeanFactoryPostProcessor(實現了Ordered) 的postProcessBeanFactory()方法* 9. 執行掃描出來的BeanFactoryPostProcessor(普通) 的postProcessBeanFactory()方法* <p>* ConfigurationClassPostProcessor就會在第2步執行,會進行掃描*/
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor// Invoke BeanDefinitionRegistryPostProcessors first, if any.Set<String> processedBeans = new HashSet<>();// 實現BeanDefinitionRegistry接口的beanFactory具有注冊、保存、移除、獲取某個BeanDefinition的功能if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();// beanFactoryPostProcessors集合一般情況下都是空的,除非我們手動調用容器的addBeanFactoryPostProcessor方法添加了// beanFactoryPostProcessors中可能包含了:普通BeanFactoryPostProcessor對象和BeanDefinitionRegistryPostProcessor對象// 對于BeanDefinitionRegistryPostProcessor對象,會執行自己的postProcessBeanDefinitionRegistry()方法for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {BeanDefinitionRegistryPostProcessor registryProcessor =(BeanDefinitionRegistryPostProcessor) postProcessor;registryProcessor.postProcessBeanDefinitionRegistry(registry);registryProcessors.add(registryProcessor);} else {regularPostProcessors.add(postProcessor);}}// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!// Separate between BeanDefinitionRegistryPostProcessors that implement// PriorityOrdered, Ordered, and the rest.List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();/*****************************************************************************/// 執行掃描出來的BeanDefinitionRegistryPostProcessor// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.// 此方法能拿到 ConfigurationClassPostProcessor 對象String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {// 判斷 ConfigurationClassPostProcessor 是否實現 PriorityOrdered接口if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {// 創建bean對象 添加到BeanDefinitionRegistryPostProcessor類型的對象集合中currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}// 升序排序sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);// 執行 ConfigurationClassPostProcessor對象的postProcessBeanDefinitionRegistry對象進行掃描invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();/*****************************************************************************/// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);for (String ppName : postProcessorNames) {// processedBeans表示該beanFactoryPostProcessor的postProcessBeanDefinitionRegistry()方法已經執行過了,不再重復執行if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));processedBeans.add(ppName);}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();/*****************************************************************************/// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.// 執行哪些沒有實現了PriorityOrdered或Ordered接口的普通BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法// 在這個過程中可能會向BeanFactory中注冊另外的BeanDefinitionRegistryPostProcessor,所以需要while,直到確定所有的BeanDefinitionRegistryPostProcessor都執行完了// 在這個過程中注冊的BeanDefinitionRegistryPostProcessor,所實現的PriorityOrdered或Ordered接口可能會不按順序執行// 比如 A注冊了B和C,B又注冊了D和E,那么B和C會按順序執行,D和E也會按順序執行,但是B、C、D、E整體不能保證是順序執行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;}}sortPostProcessors(currentRegistryProcessors, beanFactory);registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());currentRegistryProcessors.clear();}/*****************************************************************************/// Now, invoke the postProcessBeanFactory callback of all processors handled so far.// 執行完BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法后,// 再執行BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法// 執行設置BeanDefinition的方法invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);// 執行手動添加的普通BeanFactoryPostProcessor的postProcessBeanFactory()方法invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);} else {// Invoke factory processors registered with the context instance.invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);}// 執行掃描出來的普通BeanFactoryPostProcessor// Do not initialize FactoryBeans here: We need to leave all regular beans// uninitialized to let the bean factory post-processors apply to them!String[] postProcessorNames =beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,// Ordered, and the rest.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);}}// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.sortPostProcessors(priorityOrderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);// Next, invoke the BeanFactoryPostProcessors that implement Ordered.List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());for (String postProcessorName : orderedPostProcessorNames) {orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}sortPostProcessors(orderedPostProcessors, beanFactory);invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);// Finally, invoke all other BeanFactoryPostProcessors.List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());for (String postProcessorName : nonOrderedPostProcessorNames) {nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));}invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);// Clear cached merged bean definitions since the post-processors might have// modified the original metadata, e.g. replacing placeholders in values...beanFactory.clearMetadataCache();
}
通過上述代碼,我們可以看到:
- 首先判讀BeanFactory是否實現BeanDefinitionRegistry接口,實現BeanDefinitionRegistry接口的beanFactory具有注冊、保存、移除、獲取某個BeanDefinition的功能;
- 如果沒有實現,調用invokeBeanFactoryPostProcessors()方法,執行所以BeanFactoryPostProcessor的postProcessBeanFactory()方法;
- 如果實現啦,
- 遍歷所有的BeanFactoryPostProcessor,此時BeanFactoryPostProcessor集合中還是空的;
- 再往下,從BeanFactory中拿到實現BeanDefinitionRegistryPostProcessor接口的Bean,這里只是拿到BeanName;(這里可以拿到AnnotationConfigApplicationContext無參構造器時添加的ConfigurationClassPostProcessor對象);
- 遍歷這些BeanName,判斷如果實現PriorityOrdered接口的話,調用getBean方法進行實例化,其實就是創建ConfigurationClassPostProcessor Bean對象;
- 調用sortPostProcessors()方法進行排序;
- 再往下執行invokeBeanDefinitionRegistryPostProcessors()方法,這里會執行BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry()方法,其實就是執行上面ConfigurationClassPostProcessor Bean對象的postProcessBeanDefinitionRegistry()方法;完成Bean對象的掃描;
- 再往下,再次從BeanFactory中獲取實現BeanDefinitionRegistryPostProcessor接口的BeanName;
- 這里的作用是拿到我們自己設置的實現BeanDefinitionRegistryPostProcessor接口的Bean,上一步是拿到Spring容器設置的ConfigurationClassPostProcessor Bean;
- 拿到所有的實現BeanDefinitionRegistryPostProcessor接口的BeanName后,過濾掉已經執行過的(ConfigurationClassPostProcessor Bean對象),通過getBean方法創建Bean對象;
- 然后進行排序,執行他們的postProcessBeanDefinitionRegistry()方法;
- 再往下,這個while()循環的作用:擔心前兩步會漏掉,有實現BeanDefinitionRegistryPostProcessor接口的Bean沒有執行postProcessBeanDefinitionRegistry()方法,這里再做一個補充;
- 這里調用invokeBeanFactoryPostProcessors()方法,執行所有實現BeanDefinitionRegistryPostProcessor接口Bean對象的postProcessBeanFactory()方法,(這里包括執行ConfigurationClassPostProcessor Bean對象的postProcessBeanFactory()方法,詳情請移步至《Spring~配置類》);
- 再往下執行手動添加的普通BeanFactoryPostProcessor的postProcessBeanFactory()方法;
- 拿到所有實現BeanFactoryPostProcessor接口的類,先進行篩選和分類,過濾掉前面執行過的,根據PriorityOrdered、Ordered、沒有實現任何排序接口三種情況進行分類,根據PriorityOrdered、Ordered、沒有實現任何排序接口的順序執行,先創建bean對象,在執行對象的postProcessBeanFactory方法;
返回AnnotationConfigApplicationContext類的invokeBeanFactoryPostProcessors()方法;
registerBeanPostProcessors()方法
registerBeanPostProcessors()方法詳解
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {// 獲取到所有的BeanPostProcessorString[] 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.// beanProcessorTargetCount表示BeanFactory中所有的BeanPostProcessor數量,+1表示BeanPostProcessorCheckerint 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.// MergedBeanDefinitionPostProcessor排在最后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).// ApplicationListenerDetector放在所有BeanPostProcessor之后,注意ApplicationListenerDetector的equals()方法實現beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}
通過上述代碼,我們可以看到:
- 首先會拿到所有實現啦BeanPostProcessor接口的BeanName;
- 將所有的BeanPostProcessor注冊到BeanFactory中;
- 再往下,根據PriorityOrdered、Ordered、沒有實現任何排序接口三種情況進行分類;
- 根據上面的順序,先創建bean對象,把bean對象安裝順序添加到BeanFactory的beanPostProcessors屬性中;
- 最后把ApplicationListenerDetector添加到BeanFactory的beanPostProcessors屬性中;
返回AnnotationConfigApplicationContext類的registerBeanPostProcessors()方法;
ConfigurationClassPostProcessor 對象
postProcessBeanDefinitionRegistry()方法
postProcessBeanDefinitionRegistry()方法詳解
/*** Derive further bean definitions from the configuration classes in the registry.*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {int registryId = System.identityHashCode(registry);if (this.registriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);}if (this.factoriesPostProcessed.contains(registryId)) {throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);}this.registriesPostProcessed.add(registryId);// 解析配置類processConfigBeanDefinitions(registry);
}
通過上述代碼,我們可以看到,這里會調用processConfigBeanDefinitions()方法解析配置類,詳情請移步至《Spring~配置類》
返回PostProcessorRegistrationDelegate類的invokeBeanFactoryPostProcessors()方法;