前言:
文章很長,一萬多字,如果不關注細節的話只看目錄就可以。
目錄設置了縮進,代表了啓動流程中方法的調用和包含關係。
目錄基本上概述了SpringBoot啓動的基本流程。
目錄
|----|設置ApplicationContextInitializer和ApplicationListener
|----|----|根據Name初始化Initializer和Linstener的實例
|----|設置並啓動SpringApplicationRunListener
|----|----|postProcessBeanFactory
|----|----|----|初始化BeanFactory的BeanDefinition
|----|----|----|BeanDefinition註冊
|----|----|registerBeanPostProcessors分類註冊
|----|----|initMessageSource初始化信息源
|----|----|initApplicationEventMulticaster初始化事件廣播器
|----|----|----|createWebServer
|----|----|finishBeanFactoryInitialization
|----|----|----|----|getSingleton(beanName)和循環依賴的處理
|----|----|----|----|getMergedLocalBeanDefinition
|----|----|----|----|getSingleton(beanName, singletonFactory)
|----|----|----|----|----|createBean
|----|----|----|----|----|----|doCreateBean
|----|----|----|----|----|----|----|createBeanInstance獲得instanceWrapper
|----|----|----|----|----|----|----|initializeBean
|----|----|----|startWebServer
|----|----|registerShutdownHook
Spring-boot的ApplicationContext啓動結束
下面開始
main方法啓動
如果用如下代碼啓動StringBoot:
package test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication
@EnableScheduling
public class TestApplication {
public static void main(String[] args) {
SpringApplication.run(TestApplication.class, args);
}
}
SpringApplication的全路徑是org.springframework.boot.SpringApplication。
SpringApplication的run()方法進行了如下的調用:
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class[]{primarySource}, args);
}
run方法:
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
初始化SpringApplication
其中的new SpringApplication(primarySources)是初始化的方法,其代碼如下:
public SpringApplication(Class... primarySources) {
this((ResourceLoader)null, primarySources);
}
方法裏面調用的構造方法如下:
public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
this.sources = new LinkedHashSet();
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
this.addCommandLineProperties = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = new HashSet();
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
this.webApplicationType = this.deduceWebApplicationType();
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
在這個構造方法中,初始化了很多基礎屬性,裝配了Initializers和Listeners。
this.webApplicationType = this.deduceWebApplicationType();
這個方法定義了webApplicationType,最終獲得的值是WebApplicationType.SERVLET,是個枚舉。
|----|設置ApplicationContextInitializer和ApplicationListener
當前位置:初始化SpringApplication—設置ApplicationContextInitializer和ApplicationListener
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
這是Initializer和Listener的裝配方式,這裏裝配的Initializers將來會被用來構造被Spring註解所標註的類。
我們來看一下這個getSpringFactoriesInstances()方法,這個方法實際上是一個公共方法,多處都有調用,這個方法的功能是按照參數的名字,獲取在配置文件中配置好的類名。
這裏分別有兩次調用,參數是ApplicationContextInitializer和ApplicationListener,方法的代碼是這樣的:
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type) {
return this.getSpringFactoriesInstances(type, new Class[0]);
}
調用了下面的方法:
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
List<T> instances = this.createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
其中classLoader是AppClassLoader。
|----|----|讀取配置中的Name
當前位置:初始化SpringApplication—設置ApplicationContextInitializer和ApplicationListener—讀取配置中的Name
Set<String> names = new LinkedHashSet(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
這行是獲取SpringFactory的名字列表,SpringFactoriesLoader.loadFactoryNames()方法是這這樣的:
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
String factoryClassName = factoryClass.getName();
return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
此時的factoryClassName是之前傳入的參數:ApplicationContextInitializer,classLoader是之前得到的AppClassLoader,loadSpringFactories()方法是這樣的:
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
if (result != null) {
return result;
} else {
try {
Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
LinkedMultiValueMap result = new LinkedMultiValueMap();
while(urls.hasMoreElements()) {
URL url = (URL)urls.nextElement();
UrlResource resource = new UrlResource(url);
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
Iterator var6 = properties.entrySet().iterator();
while(var6.hasNext()) {
Entry<?, ?> entry = (Entry)var6.next();
List<String> factoryClassNames = Arrays.asList(StringUtils.commaDelimitedListToStringArray((String)entry.getValue()));
result.addAll((String)entry.getKey(), factoryClassNames);
}
}
cache.put(classLoader, result);
return result;
} catch (IOException var9) {
throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var9);
}
}
}
該方法一開始從緩存中獲取factory的名字列表,剛開始初始化時cache是空的,需要重新獲取名字。
從後面的代碼中可以看到,classLoader讀取了所有能掃描到的各jar包中的META-INF /spring.factories文件,能掃描出一大堆,多數都是spring的jar和spring-boot的jar,下面列舉幾個:
1,sping-beans-5.0.5.RELEASE.jar,他的META-INF /spring.factories文件中只有一行:
org.springframework.beans.BeanInfoFactory=org.springframework.beans.ExtendedBeanInfoFactory
2,spring-boot-2.0.1.RELEASE.jar,他的META-INF /spring.factories文件中寫了一大堆:
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader
# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener
# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers
# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor
# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer
# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter
3, spring-boot-autoconfigure-2.0.1.RELEASE.jar,他的META-INF /spring.factories文件中寫了更大的一堆,不貼了。
4, spring-boot-starter-dubbo-1.0.0.jar,他的META-INF /spring.factories文件中寫了這幾個factory:
org.springframework.context.ApplicationContextInitializer=\
io.dubbo.springboot.DubboConfigurationApplicationContextInitializer
org.springframework.context.ApplicationListener=\
io.dubbo.springboot.DubboHolderListener
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
io.dubbo.springboot.DubboAutoConfiguration
5,spring-data-redis-2.0.6.RELEASE.jar,他的META-INF /spring.factories文件中只有一行:
org.springframework.data.repository.core.support.RepositoryFactorySupport=org.springframework.data.redis.repository.support.RedisRepositoryFactory
反正名字中帶ApplicationContextInitializer和ApplicationListener的,全都放進result裏,然後放進cache裏。
獲取了spring.factories中的配置後,loadSpringFactories方法結束。
緊接着調用了getOrDefault()方法,傳入了factoryClassName參數,此時factoryClassName的值是org.springframework.context.ApplicationContextInitializer,作用是隻留下配置項中key是org.springframework.context.ApplicationContextInitializer的配置項,然後返回這些ApplicationContextInitializer的類名。
所以,想要自定義Initializer的話,可以按照上面的套路進行設置,另外,自定義的Initializer類需要和上面這些Initializer一樣,實現ApplicationContextInitializer接口並實現initialize方法。
|----|----|根據Name初始化Initializer和Linstener的實例
當前位置:初始化SpringApplication—設置ApplicationContextInitializer和ApplicationListener—根據Name初始化Initializer和Linstener的實例
回到SpringApplication的getSpringFactoriesInstances()方法,獲得了names之後,調用createSpringFactoriesInstances方法,創建這些Factory的實例:
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args, Set<String> names) {
List<T> instances = new ArrayList(names.size());
Iterator var7 = names.iterator();
while(var7.hasNext()) {
String name = (String)var7.next();
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
T instance = BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
} catch (Throwable var12) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, var12);
}
}
return instances;
}
其實就是使用反射,獲得class,獲得構造方法,用構造方法創建對象。
至此,SpringApplication中的Initalizer和Linstener的列表創建完成。
至此new SpringApplication(primarySources)方法執行成功,SpringApplication被初始化,再貼一下這裏的代碼:
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
之後調用了run方法,開始啓動SpringApplication。
SpringApplication啓動
SpringApplication的run(String... args)方法代碼是這樣的:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
|----|設置並啓動SpringApplicationRunListener
當前位置:SpringApplication啓動—設置並啓動SpringApplicationRunListener
方法一開始用getRunListeners()方法獲得並啓動了SpringApplicationRunListeners,其實方法裏面調用的也是之前調用過的getSpringFactoriesInstances()方法,只不過這時傳的參數是SpringApplicationRunListeners.class,得到的Listener也只有一個,就是SpringApplicationRunListener。
調用
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
初始化了environment,這個environment由StandardServletEnvironment類實現。
|----|生成ApplicationContext對象
當前位置:SpringApplication啓動—生成ApplicationContext對象
後面的
context = this.createApplicationContext();
是初始化Application上下文的方法,其代碼如下:
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch(this.webApplicationType) {
case SERVLET:
contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
break;
case REACTIVE:
contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
break;
default:
contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
}
} catch (ClassNotFoundException var3) {
throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
}
}
return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
}
此時的this.applicationContextClass是null,this.webApplicationType之前Application初始化的時候定義的SERVLET,所以contextClass 是org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext,並在方法返回之前用反射進行了初始化。這個類很重要,會在後面作爲上下文初始化的主要的類,很多方法都是由這個類或者其父類實現的。
需要注意的是,AnnotationConfigServletWebServerApplicationContext類的父類的父類,GenericApplicationContext,在構造的時候定義了BeanFactory,由DefaultListableBeanFactory類實現,他的構造代碼如下:
public GenericApplicationContext() {
this.customClassLoader = false;
this.refreshed = new AtomicBoolean();
this.beanFactory = new DefaultListableBeanFactory();
}
這個GenericApplicationContext類的直接父類就是AbstractApplicationContext。
回到SpringApplication的run()方法,在得到了ApplicationContext之後,再一次調用了getSpringFactoriesInstances()方法,獲得了配置文件中配置的SpringBootExceptionReporter類(實際上只得到了一個FailureAnalyzer)。
|----|prepareContext
當前位置:SpringApplication啓動—prepareContext
接下來調用了this.prepareContext()方法,方法的代碼如下:
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
this.postProcessApplicationContext(context);
this.applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
this.logStartupInfo(context.getParent() == null);
this.logStartupProfileInfo(context);
}
context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
context.getBeanFactory().registerSingleton("springBootBanner", printedBanner);
}
Set<Object> sources = this.getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
this.load(context, sources.toArray(new Object[0]));
listeners.contextLoaded(context);
}
方法一開始綁定了environment,關聯了classloader。
|----|----|Initializer初始化
當前位置:SpringApplication啓動—prepareContext—Initializer初始化
然後調用了this.applyInitializers()方法,這個方法用來綁定之前的Initializer,this.applyInitializers()方法代碼如下:
protected void applyInitializers(ConfigurableApplicationContext context) {
Iterator var2 = this.getInitializers().iterator();
while(var2.hasNext()) {
ApplicationContextInitializer initializer = (ApplicationContextInitializer)var2.next();
Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(), ApplicationContextInitializer.class);
Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
initializer.initialize(context);
}
}
在這個方法中,循環調用了每個Initializer的initialize()方法,這個initialize()是每個ApplicationContextInitializer必須重寫的,以spring-boot-starter-dubbo-1.0.0.jar中配置的io.dubbo.springboot.DubboConfigurationApplicationContextInitializer爲例:
public class DubboConfigurationApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
public DubboConfigurationApplicationContextInitializer() {
}
public void initialize(ConfigurableApplicationContext applicationContext) {
Environment env = applicationContext.getEnvironment();
String scan = env.getProperty("spring.dubbo.scan");
if (scan != null) {
AnnotationBean scanner = (AnnotationBean)BeanUtils.instantiate(AnnotationBean.class);
scanner.setPackage(scan);
scanner.setApplicationContext(applicationContext);
applicationContext.addBeanFactoryPostProcessor(scanner);
applicationContext.getBeanFactory().addBeanPostProcessor(scanner);
applicationContext.getBeanFactory().registerSingleton("annotationBean", scanner);
}
}
}
在Initializer類的initialize()方法中,需要定義一個BeanProcessor,BeanProcessor用於被註解變量的初始化,需要實現DisposableBean, BeanFactoryPostProcessor, BeanPostProcessor, ApplicationContextAware接口,並實現其中的幾個接口。定義好的BeanProcessor需要添加到applicationContext的BeanFactory中,比如上面代碼的這兩行:
applicationContext.addBeanFactoryPostProcessor(scanner);
applicationContext.getBeanFactory().addBeanPostProcessor(scanner);
回到SpringApplication的prepareContext()方法,調用完成applyInitailizers()方法後,調用了
listeners.contextPrepared(context);
現在的listeners裏面只有一個EventPublishingRunListener,然而這個listener的contextPrepared方法裏什麼都沒有寫。
|----|refreshContext
當前位置:SpringApplication啓動—refreshContext
再往前回到SpringApplication的run方法,this.prepareContext方法執行完成後,下一步是執行this.refreshContext()方法,這個方法是處理Spring上下文的關鍵方法。
重頭戲來了,從這裏開始,Spring的上下文開始初始化了。SpringBoot啓動時,上下文的實現類是AnnotationConfigServletWebServerApplicationContext,後面調用的ApplicationContext,ConfigurableApplicationContext等上下文的方法,本質上都是由這個類及其父類實現的。
SpringApplication的this.refreshContext()方法代碼如下:
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException var3) {
;
}
}
}
主要是其中的this. refresh()方法:
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext)applicationContext).refresh();
}
applicationContext 參數是由之前的AnnotationConfigServletWebServerApplicationContext類實現的,他的refresh()方法是由他的父類AbstractApplicationContext實現的:
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
這是一個同步方法,同步的變量是這個類的startupShutdownMonitor變量。
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
得到的是一個DefaultListableBeanFactory工廠類,之前生成ApplicationContext對象的時候初始化的,這個工廠類後面一直會用。
this.prepareBeanFactory(beanFactory);
這個方法的實現就在AbstractApplicationContext類中,方法組裝了BeanFactory的BeanClassLoader,BeanPostProcessor等組件,並註冊了幾個單例對象,比如environment,systemProperties,systemEnvironment等。
|----|----|postProcessBeanFactory
當前位置:SpringApplication啓動—refreshContext—postProcessBeanFactory
this.postProcessBeanFactory(beanFactory);
這個方法是在AnnotationConfigServletWebServerApplicationContext類中實現的,代碼如下:
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));
}
}
其中super.postProcessBeanFactory(beanFactory);調用了父類ServletWebServerApplicationContext的postProcessBeanFactory()方法:
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
實際上是向BeanFactory中註冊了一個WebApplicationContextServletContextAwareProcessor。
下面的
if (this.basePackages != null && this.basePackages.length > 0)
this.scanner.scan(this.basePackages);
}
這部分是掃描配置過的路徑,並獲得classPath路徑下相關類的BeanDefinition。據說可以在啓動類中使用@ComponentScan(basePackages = {"com.xxx.*"})或者SpringBoot的@SpringBootApplication(scanBasePackages={"com.xxx.*"})註解來配置,但是我試了一下貌似沒有用,還不清楚具體應該怎麼配置。
|----|----|----|初始化BeanFactory的BeanDefinition
當前位置:SpringApplication啓動—refreshContext—invokeBeanFactoryPostProcessors—初始化BeanFactory的BeanDefinition
this.invokeBeanFactoryPostProcessors(beanFactory);
這個方法處理了BeanFactory中的BeanFactoryPostProcessors,代碼如下:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean("loadTimeWeaver")) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
方法最開始,調用了PostProcessorRegistrationDelegate類的invokeBeanFactoryPostProcessors()方法,這個方法比較長:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
Set<String> processedBeans = new HashSet();
int var9;
ArrayList currentRegistryProcessors;
String[] postProcessorNames;
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new LinkedList();
Iterator var6 = beanFactoryPostProcessors.iterator();
while(var6.hasNext()) {
BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next();
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
currentRegistryProcessors = new ArrayList();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var18 = postProcessorNames;
var9 = postProcessorNames.length;
int var10;
String ppName;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
var18 = postProcessorNames;
var9 = postProcessorNames.length;
for(var10 = 0; var10 < var9; ++var10) {
ppName = var18[var10];
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);
currentRegistryProcessors.clear();
boolean reiterate = true;
while(reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
String[] var21 = postProcessorNames;
var10 = postProcessorNames.length;
for(int var28 = 0; var28 < var10; ++var28) {
String ppName = var21[var28];
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);
currentRegistryProcessors.clear();
}
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
} else {
invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
}
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
currentRegistryProcessors = new ArrayList();
postProcessorNames = postProcessorNames;
int var22 = postProcessorNames.length;
String ppName;
for(var9 = 0; var9 < var22; ++var9) {
ppName = postProcessorNames[var9];
if (!processedBeans.contains(ppName)) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
currentRegistryProcessors.add(ppName);
}
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)priorityOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var23 = orderedPostProcessorNames.iterator();
while(var23.hasNext()) {
String postProcessorName = (String)var23.next();
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var26 = currentRegistryProcessors.iterator();
while(var26.hasNext()) {
ppName = (String)var26.next();
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
beanFactory.clearMetadataCache();
}
傳入的參數beanFactory是一個DefaultListableBeanFactory對象,DefaultListableBeanFactory類實現了BeanDefinitionRegistry接口,所以
if (beanFactory instanceof BeanDefinitionRegistry) {
判斷通過,後面定義了兩個列表,regularPostProcessors和registryProcessors,分別記錄參數beanFactoryPostProcessors中的BeanDefinitionRegistryPostProcessor及其他BeanProcesor,如果是BeanDefinitionRegistryPostProcessor實例,比如ConfigurationWarningsApplicationContextInitializer,則需要調用他的postProcessBeanDefinitionRegistry方法。這個方法初始化了一些BeanFactory的BeanDefinition,並把他們放到了DefaultListableBeanFactory的BeanDefinitionMap和BeanDefinitionNams這兩個map中。
|----|----|----|BeanDefinition註冊
當前位置:SpringApplication啓動—refreshContext—invokeBeanFactoryPostProcessors—BeanDefinition註冊
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
調用了一系列特別長的邏輯,得到的是一個ConfigurationClassPostProcessor,並添加到registryProcessors列表中,並在後面的
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
代碼中調用了這個Processor的postProcessBeanDefinitionRegistry()方法:
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);
} else if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + registry);
} else {
this.registriesPostProcessed.add(registryId);
this.processConfigBeanDefinitions(registry);
}
}
傳入參數是DefaultListableBeanFactory,獲得了他的HashCode之後存入了ConfigurationClassPostProcessor的registriesPostProcessed這個set中,然後調用了他的processConfigBeanDefinitions()方法。這個方法處理了配置類並把DefaultListableBeanFactory中的BeanDefinition進行註冊。
和ConfigurationClassPostProcessor相同,後面用同樣的方法,處理了一個internalConfigurationAnnotationProcessor。
invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory);
invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory);
把registryProcessors和regularPostProcessors分別調用了invokeBeanFactoryPostProcessors()方法進行處理,調用了他們的postProcessBeanFactory方法。
比如其中ConfigurationClassPostProcessor的postProcessBeanFactory方法:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);
} else {
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
this.processConfigBeanDefinitions((BeanDefinitionRegistry)beanFactory);
}
this.enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor(beanFactory));
}
}
在factoriesPostProcessed屬性中記錄了傳入的DefaultListableBeanFactory的hashCode之後,把這個ConfigurationClassPostProcessor加到了DefaultListableBeanFactory的BeanPostProcessors列表中。
dubbo的AnnotationBean的postProcessBeanFactory方法也有一些獨有的邏輯。
invokeBeanFactoryPostProcessors方法後面的代碼也是在用同樣的方式處理了不同的BeanPostFactoryProcessor。
invokeBeanFactoryPostProcessors完成後,回到AbstractApplicationContext的invokeBeanFactoryPostProcessors方法,beanFactory的tempClassLoader是null,於是方法結束,回到AbstractApplicationContext的refresh()方法。
|----|----|registerBeanPostProcessors分類註冊
當前位置:SpringApplication啓動—refreshContext—registerBeanPostProcessors分類註冊
refresh()方法在執行完invokeBeanFactoryPostProcessors()方法後,開始執行this.registerBeanPostProcessors()方法:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
調用了PostProcessorRegistrationDelegate的registerBeanPostProcessors()方法:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new PostProcessorRegistrationDelegate.BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList();
List<BeanPostProcessor> internalPostProcessors = new ArrayList();
List<String> orderedPostProcessorNames = new ArrayList();
List<String> nonOrderedPostProcessorNames = new ArrayList();
String[] var8 = postProcessorNames;
int var9 = postProcessorNames.length;
String ppName;
BeanPostProcessor pp;
for(int var10 = 0; var10 < var9; ++var10) {
ppName = var8[var10];
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
pp = (BeanPostProcessor)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);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
List<BeanPostProcessor> orderedPostProcessors = new ArrayList();
Iterator var14 = orderedPostProcessorNames.iterator();
while(var14.hasNext()) {
String ppName = (String)var14.next();
BeanPostProcessor pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)orderedPostProcessors);
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList();
Iterator var17 = nonOrderedPostProcessorNames.iterator();
while(var17.hasNext()) {
ppName = (String)var17.next();
pp = (BeanPostProcessor)beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, (List)nonOrderedPostProcessors);
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, (List)internalPostProcessors);
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
方法最開始,把所有的BeanPostProcessor按照實現的接口,分成了PriorityOrdered,Ordered,nonOrdered三個列表,優先級依次降低,然後後續代碼從PriorityOrdered列表開始,調用這樣的方法:
registerBeanPostProcessors(beanFactory, (List)priorityOrderedPostProcessors);
把這些BeanPostProcessor加到BeanPostProcessors列表中。
實現了PriorityOrdered接口的BeanPostProcessor有:
AutowiredAnnotationBeanPostProcessor
RequiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
實現了Ordered接口的BeanPostProcessor有:
internalScheduledAnnotationProcessor
methodValidationPostProcessor
未實現PriorityOrdered和Ordered接口的BeanPostProcessor有:
webServerFactoryCustomizerBeanPostProcessor
errorPageRegistrarBeanPostProcessor
annotationBean
this.registerBeanPostProcessors()方法執行結束。
|----|----|initMessageSource初始化信息源
當前位置:SpringApplication啓動—refreshContext—initMessageSource初始化信息源
繼續看refresh方法,registerBeanPostProcessors()方法之後,下面調用的是
this.initMessageSource();
方法代碼如下:
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
if (beanFactory.containsLocalBean("messageSource")) {
this.messageSource = (MessageSource)beanFactory.getBean("messageSource", MessageSource.class);
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource)this.messageSource;
if (hms.getParentMessageSource() == null) {
hms.setParentMessageSource(this.getInternalParentMessageSource());
}
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Using MessageSource [" + this.messageSource + "]");
}
} else {
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(this.getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton("messageSource", this.messageSource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Unable to locate MessageSource with name 'messageSource': using default [" + this.messageSource + "]");
}
}
}
這個方法從BeanFactory中獲取messageSource對象,如果沒有則定義了一個DelegatingMessageSource對象,設置了父MessageSource,並且在BeanFactory中註冊。
|----|----|initApplicationEventMulticaster初始化事件廣播器
當前位置:SpringApplication啓動—refreshContext—initApplicationEventMulticaster初始化事件廣播器
initMessageSource()方法完成後,調用的是:
this.initApplicationEventMulticaster();
其中的代碼邏輯和初始化信息源時相同,先從BeanFactory中獲取,BeanFactory中沒有則定義一個SimpleApplicationEventMulticaster對象,並且在BeanFactory中註冊。
|----|----|onRefresh
當前位置:SpringApplication啓動—refreshContext—onRefresh
this.onRefresh();
這個方法由AnnotationConfigServletWebServerApplicationContext的父類ServletWebServerApplicationContext實現,代碼如下:
protected void onRefresh() {
super.onRefresh();
try {
this.createWebServer();
} catch (Throwable var2) {
throw new ApplicationContextException("Unable to start web server", var2);
}
}
其中的super.onRefresh();是在GenericWebApplicationContext中實現的:
protected void onRefresh() {
this.themeSource = UiApplicationContextUtils.initThemeSource(this);
}
初始化了一個主題,不知道這個是做什麼用的。
|----|----|----|createWebServer
當前位置:SpringApplication啓動—refreshContext—onRefresh—createWebServer
繼續看onRefresh()方法,this.createWebServer();生成了一個TomcatWebServer,方法代碼如下:
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = this.getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = this.getWebServerFactory();
this.webServer = factory.getWebServer(new ServletContextInitializer[]{this.getSelfInitializer()});
} else if (servletContext != null) {
try {
this.getSelfInitializer().onStartup(servletContext);
} catch (ServletException var4) {
throw new ApplicationContextException("Cannot initialize servlet context", var4);
}
}
this.initPropertySources();
}
在這個方法中,得到的ServletWebServerFactory是一個TomcatServletWebServerFactory,並調用他的getWebServer()方法生成了一個WebServer,其中getWebServer()方法如下:
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = this.baseDirectory != null ? this.baseDirectory : this.createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
Connector connector = new Connector(this.protocol);
tomcat.getService().addConnector(connector);
this.customizeConnector(connector);
tomcat.setConnector(connector);
tomcat.getHost().setAutoDeploy(false);
this.configureEngine(tomcat.getEngine());
Iterator var5 = this.additionalTomcatConnectors.iterator();
while(var5.hasNext()) {
Connector additionalConnector = (Connector)var5.next();
tomcat.getService().addConnector(additionalConnector);
}
this.prepareContext(tomcat.getHost(), initializers);
return this.getTomcatWebServer(tomcat);
}
這個方法新建了一個Tomcat類,初始化了他的一些參數,最後調用getTomcatWebServer()方法得到了一個TomcatWebServer,這個TomcatWebServer後續會啓動。
this.getTomcatWebServer()方法如下:
protected TomcatWebServer getTomcatWebServer(Tomcat tomcat) {
return new TomcatWebServer(tomcat, this.getPort() >= 0);
}
其中的
new TomcatWebServer(tomcat, this.getPort() >= 0);
創建並初始化了這個WebServer,並且把其中的Tomcat對象啓動了,代碼如下:
public TomcatWebServer(Tomcat tomcat, boolean autoStart) {
this.monitor = new Object();
this.serviceConnectors = new HashMap();
Assert.notNull(tomcat, "Tomcat Server must not be null");
this.tomcat = tomcat;
this.autoStart = autoStart;
this.initialize();
}
這裏的autoStart是否自動啓動,如果之前的端口號大於0則是true。
|----|----|----|----|tomcat啓動
當前位置:SpringApplication啓動—refreshContext—onRefresh—createWebServer—tomcat啓動
最後的this.initialize();方法:
private void initialize() throws WebServerException {
logger.info("Tomcat initialized with port(s): " + this.getPortsDescription(false));
Object var1 = this.monitor;
synchronized(this.monitor) {
try {
this.addInstanceIdToEngineName();
Context context = this.findContext();
context.addLifecycleListener((event) -> {
if (context.equals(event.getSource()) && "start".equals(event.getType())) {
this.removeServiceConnectors();
}
});
this.tomcat.start();
this.rethrowDeferredStartupExceptions();
try {
ContextBindings.bindClassLoader(context, context.getNamingToken(), this.getClass().getClassLoader());
} catch (NamingException var5) {
;
}
this.startDaemonAwaitThread();
} catch (Exception var6) {
this.stopSilently();
throw new WebServerException("Unable to start embedded Tomcat", var6);
}
}
}
可以看到,方法中tomcat容器啓動了,但是沒有啓動connector,connector會在後面啓動webServer的時候啓動。
另外看到方法最後調用了startDaemonAwaitThread()方法,看一下這個是做什麼的:
private void startDaemonAwaitThread() {
Thread awaitThread = new Thread("container-" + containerCounter.get()) {
public void run() {
TomcatWebServer.this.tomcat.getServer().await();
}
};
awaitThread.setContextClassLoader(this.getClass().getClassLoader());
awaitThread.setDaemon(false);
awaitThread.start();
}
方法啓動了一個線程,名字是container開頭,非守護線程,這個線程調用了tomcatServer的await()方法,此處的tomcatServer是由StandardServer實現的,他的await()方法特別長,內容大概就是創建了一個while循環,而且會一直循環下去。因爲這個線程存在, Tomcat在啓動的代碼執行完後也不會關閉進程。
|----|----|registerListeners
當前位置:SpringApplication啓動—refreshContext—registerListeners
this.registerListeners();
代碼如下:
protected void registerListeners() {
Iterator var1 = this.getApplicationListeners().iterator();
while(var1.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var1.next();
this.getApplicationEventMulticaster().addApplicationListener(listener);
}
String[] listenerBeanNames = this.getBeanNamesForType(ApplicationListener.class, true, false);
String[] var7 = listenerBeanNames;
int var3 = listenerBeanNames.length;
for(int var4 = 0; var4 < var3; ++var4) {
String listenerBeanName = var7[var4];
this.getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
Iterator var9 = earlyEventsToProcess.iterator();
while(var9.hasNext()) {
ApplicationEvent earlyEvent = (ApplicationEvent)var9.next();
this.getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
註冊了之前組裝好的ApplicationListener,並把他們加到AbstractApplicationContext的applicationEventMulticaster的applicationListeners這個set中去。
此處的applicationEventMulticaster是由SimpleApplicationEventMulticaster類實現的。
從BeanFactory中獲取ApplicationLinster的名字,並把他們加到AbstractApplicationContext的applicationEventMulticaster的applicationListenerBeans這個set中去。
獲得AbstractApplicationContext的earlyApplicationEvents,調用applicationEventMulticaster的multicastEvent方法,這個方法在SimpleApplicationEventMulticaster類中實現:
public void multicastEvent(ApplicationEvent event) {
this.multicastEvent(event, this.resolveDefaultEventType(event));
}
public void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType) {
ResolvableType type = eventType != null ? eventType : this.resolveDefaultEventType(event);
Iterator var4 = this.getApplicationListeners(event, type).iterator();
while(var4.hasNext()) {
ApplicationListener<?> listener = (ApplicationListener)var4.next();
Executor executor = this.getTaskExecutor();
if (executor != null) {
executor.execute(() -> {
this.invokeListener(listener, event);
});
} else {
this.invokeListener(listener, event);
}
}
}
不過springboot啓動到這裏時earlyApplicationEvents屬性裏沒有值。
|----|----|finishBeanFactoryInitialization
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization
registerListeners()方法執行結束,refresh()方法下一步執行的是:
this.finishBeanFactoryInitialization(beanFactory);
方法代碼如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
}
方法最後的
beanFactory.preInstantiateSingletons();
初始化BeanFactory中組裝好的標註爲單例的對象,此時BeanFactory依然由DefaultListableBeanFactory實現,他的preInstantiateSingletons方法是這樣的:
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
在這個方法中,循環了DefaultListableBeanFactory中記錄的所有bean的name,並且最終調用了this.getBean()方法,這個方法在DefaultListableBeanFactory的父類AbstractBeanFactory中,代碼如下:
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
|----|----|----|doGetBean
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean
然後是doGetBean方法:
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) {
if (this.logger.isDebugEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
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);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
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];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
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 {
String scopeName = mbd.getScope();
Scope scope = (Scope)this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider defining a scoped proxy for this bean if you intend to refer to it from a singleton", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
} else {
return convertedBean;
}
} catch (TypeMismatchException var25) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", var25);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
} else {
return bean;
}
}
|----|----|----|----|getSingleton(beanName)和循環依賴的處理
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getSingleton(beanName)
在該方法中首先從單例列表中獲取bean:
Object sharedInstance = this.getSingleton(beanName);
這裏getSingleton()方法的代碼如下:
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
這個方法是Spring解決循環依賴的關鍵方法,在這個方法中,使用了三層列表來查詢的方式,這三層列表分別是:
singletonObjects
earlySingletonObjects
singletonFactories
這個方法中用到的幾個判斷邏輯,體現了Spring解決循環依賴的思路,不過實際上對象被放入這三層的順序是和方法查詢的循序相反的,也就是說,在循環依賴出現時,對象會先進入singletonFactories,然後earlySingletonObjects,然後singletonObjects,看一下其中的邏輯:
1,
Object singletonObject = this.singletonObjects.get(beanName);
方法首先從singletonObjects中獲取對象,當Spring準備新建一個對象時,singletonObjects列表中是沒有這個對象的,然後進入下一步。
2,
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName))
除了判斷null之外,有一個isSingletonCurrentlyInCreation的判斷,實際上當Spring初始化了一個依賴注入的對象,但還沒注入對象屬性的時候,Spring會把這個bean加入singletonsCurrentlyInCreation這個set中,也就是把這個對象標記爲正在創建的狀態,這樣,如果Spring發現要創建的bean在singletonObjects中沒有,但在singletonsCurrentlyInCreation中有,基本上就可以認定爲循環依賴了。
舉個例子:對象A和對象B循環依賴,那麼初始化對象A之後(執行了構造方法),要把A放入singletonsCurrentlyInCreation,對象A依賴了對象B,那麼就要再初始化對象B,如果這個對象B又依賴了對象A,也就是形成了循環依賴,那麼當我們注入對象B中的屬性A時,進入這個代碼邏輯,就會發現,我們要注入的對象A已經在singletonsCurrentlyInCreation中了,後面的邏輯就該處理這種循環依賴了。
3,
singletonObject = this.earlySingletonObjects.get(beanName);
這裏引入了earlySingletonObjects列表,這是個爲了循環依賴而存在的列表,從名字就可以看到,是個預創建的對象列表,剛剛創建的對象在這個列表裏一般也沒有。
4,
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
earlySingletonObjects也沒有則從singletonFactories中獲取,前面說到singletonFactories是對象保存的第一步,實際上對象初始化後,可能還沒有注入對象的依賴,就把對象放入了這個列表。
如果是循環依賴,此時的singletonFactories中一般是會存在目標對象的,舉個例子:對象A和對象B循環依賴,那麼初始化了對象A(執行了構造方法),還沒有注入對象A的依賴時,就會把A放入singletonFactories,然後開始注入A的依賴,發現A依賴B,那麼需要構對象B,構造過程也是執行了B的構造後就把B放到singletonFactories,然後開始注入B的依賴,發現B依賴A,在第二步中提到,此時A已經在singletonsCurrentlyInCreation列表裏了,所以會進入此段代碼邏輯,而且此時時對象A在singletonFactories中確實存在,因爲這已經是第二次試圖創建對象A了。
5,
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
代碼到這裏基本已經確定我們要創建的這個對象已經發生循環依賴了,然後Spring進行了這樣的操作,把這個對象加入到earlySingletonObjects中,然後把該對象從singletonFactories中刪掉。
6,其實上面5步已經執行完了該方法的代碼,這裏加的第6步是爲了解釋循環依賴的結果。在這個方法的代碼之後,會把bean完整的進行初始化和依賴的注入,在完成了bean的初始化後,後面代碼邏輯中會調用一個這樣的方法:
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
後面的代碼會看到這個方法,這個方法中有個小小的子方法addSingleton(),他的代碼是這樣的:
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
這個方法處理的是已經注入完依賴的bean,把bean放入singletonObjects中,並把bean從earlySingletonObjects和singletonFactories中刪除,這個方法和上面分析的方法組成了Spring處理循環依賴的邏輯。
綜上,Spring處理循環依賴的流程大概就是以下這樣,假設對象A和對象B循環依賴:
步驟 | 操作 | 三層列表中的內容 |
---|---|---|
1 | 開始初始化對象A |
singletonFactories: earlySingletonObjects: singletonObjects: |
2 | 調用A的構造,把A放入singletonFactories |
singletonFactories:A earlySingletonObjects: singletonObjects: |
3 | 開始注入A的依賴,發現A依賴對象B |
singletonFactories:A earlySingletonObjects: singletonObjects: |
4 | 開始初始化對象B |
singletonFactories:A earlySingletonObjects: singletonObjects: |
5 | 調用B的構造,把B放入singletonFactories |
singletonFactories:A,B earlySingletonObjects: singletonObjects: |
6 | 開始注入B的依賴,發現B依賴對象A |
singletonFactories:A,B earlySingletonObjects: singletonObjects: |
7 |
開始初始化對象A,發現A在singletonFactories裏有,則直接獲取A, 把A放入earlySingletonObjects,把A從singletonFactories刪除 |
singletonFactories:B earlySingletonObjects:A singletonObjects: |
8 | 對象B的依賴注入完成 |
singletonFactories:B earlySingletonObjects:A singletonObjects: |
9 |
對象B創建完成,把B放入singletonObjects, 把B從earlySingletonObjects和singletonFactories中刪除 |
singletonFactories: earlySingletonObjects:A singletonObjects:B |
10 | 對象B注入給A,繼續注入A的其他依賴,直到A注入完成 |
singletonFactories: earlySingletonObjects:A singletonObjects:B |
11 |
對象A創建完成,把A放入singletonObjects, 把A從earlySingletonObjects和singletonFactories中刪除 |
singletonFactories: earlySingletonObjects: singletonObjects:A,B |
12 | 循環依賴處理結束,A和B都初始化和注入完成 |
singletonFactories: earlySingletonObjects: singletonObjects:A,B |
回到Spring源碼解析,如果單例列表中沒有該bean,則繼續後面代碼。SpringBoot剛啓動時Bean還沒有初始化,所以一般此時sharedInstance是null。除了SpringBoot初始化之外,啓動後對Bean的使用也會調用這個doGetBean來獲得代理,那時候這裏的sharedInstance就不是null了,可以直接獲得。
BeanFactory parentBeanFactory = this.getParentBeanFactory();
從父級Factory中獲取該Bean,不過DefaultListableBeanFactory沒有父級工廠。
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
此處的typeCheckOnly是調用該方法的時候傳來的false,於是調用this.markBeanAsCreate方法把該bean標記爲created。實際上是在AbstractBeanFactory的alreadyCreated這個set中添加了該beanName。
另外,這個方法把beanName從mergedBeanDefinition這個map中去掉了。
|----|----|----|----|getMergedLocalBeanDefinition
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getMergedLocalBeanDefinition
進入try代碼塊中,首先根據beanName獲得了BeanDefinition:
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.getMergedLocalBeanDefinition方法的代碼:
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
RootBeanDefinition mbd = (RootBeanDefinition)this.mergedBeanDefinitions.get(beanName);
return mbd != null ? mbd : this.getMergedBeanDefinition(beanName, this.getBeanDefinition(beanName));
}
之前的方法把beanName從mergedBeanDefinition這個map中去掉了,所以mbd是null,後面調用了this.getBeanDefinition()方法,這個方法在AbstractBeanFactory中是抽象類,具體實現在DefaultListableBeanFactory中:
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
} else {
return bd;
}
}
實際上是從BeanDefinitionMap中獲取了一個BeanDefinition,不過這個BeanDefinition不會成爲最終bean使用的definition,一般都是複製了裏面的屬性。
獲得了BeanDefinition後,作爲參數傳入了this.getMergedBeanDefinition()方法中,方法代碼如下:
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException {
return this.getMergedBeanDefinition(beanName, bd, (BeanDefinition)null);
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) throws BeanDefinitionStoreException {
Map var4 = this.mergedBeanDefinitions;
synchronized(this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
if (containingBd == null) {
mbd = (RootBeanDefinition)this.mergedBeanDefinitions.get(beanName);
}
if (mbd == null) {
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition)bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
BeanDefinition pbd;
try {
String parentBeanName = this.transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = this.getMergedBeanDefinition(parentBeanName);
} else {
BeanFactory parent = this.getParentBeanFactory();
if (!(parent instanceof ConfigurableBeanFactory)) {
throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent");
}
pbd = ((ConfigurableBeanFactory)parent).getMergedBeanDefinition(parentBeanName);
}
} catch (NoSuchBeanDefinitionException var10) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", var10);
}
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
}
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope("singleton");
}
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
}
if (containingBd == null && this.isCacheBeanMetadata()) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
return mbd;
}
}
方法最開始還是先從mergedBeanDefinitions嘗試獲得BeanDefinition,但是此時顯然只能是null,要不也不會來到這個方法了。
後面的代碼判斷BeanDefinition是否有父級BeanDefinition。
如果沒有父級BeanDefinition:
if (bd.getParentName() == null) {
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition)bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
}
如果沒有父級則創建新的RootBeanDefinition,然後有另外一個判斷,根據是否是RootBeanDefinition調用了兩種不同的創建方式,但是實際上都是複製了一部分屬性,調用的代碼也基本相同,只不過是實現類不同,而且兩種實現類還是父子類關係。
如果有父級BeanDefinition:
} else {
BeanDefinition pbd;
try {
String parentBeanName = this.transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = this.getMergedBeanDefinition(parentBeanName);
} else {
BeanFactory parent = this.getParentBeanFactory();
if (!(parent instanceof ConfigurableBeanFactory)) {
throw new NoSuchBeanDefinitionException(parentBeanName, "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + "': cannot be resolved without an AbstractBeanFactory parent");
}
pbd = ((ConfigurableBeanFactory)parent).getMergedBeanDefinition(parentBeanName);
}
} catch (NoSuchBeanDefinitionException var10) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition '" + bd.getParentName() + "'", var10);
}
}
則要先獲得父級BeanDefinition,並且遞歸調用getMergedBeanDefinition()方法,以父級BeanDefinition獲得子BeanDefinition,最終以此獲得Bean自己的RootBeanDefinition,所以最終的RootBeanDefinition是一個父子合併後的結果,這可能是方法名中Merged這個詞存在的原因吧。
方法最後把得到的RootBeanDefinition存到mergedBeanDefinitions這個map中。
回到AbstractBeanFactory的doGetBean()方法,
this.checkMergedBeanDefinition(mbd, beanName, args);
是檢查bean是否是抽象的,如果是抽象類則拋異常。
後面通過調用RootBeanDefinition的getDependsOn()方法獲得了Bean依賴的類,並且立刻初始化了他們。
|----|----|----|----|getSingleton(beanName, singletonFactory)
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getSingleton(beanName, singletonFactory)
後面判斷BeanDefinition是否是單例的,如果是單例的,執行的代碼是:
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
用了Lambda表達式,其中this.getSingleton()方法是由DefaultListableBeanFactory的父類DefaultSingletonBeanRegistry實現,代碼如下:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
this.beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException var16) {
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw var16;
}
} catch (BeanCreationException var17) {
BeanCreationException ex = var17;
if (recordSuppressedExceptions) {
Iterator var8 = this.suppressedExceptions.iterator();
while(var8.hasNext()) {
Exception suppressedException = (Exception)var8.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
if (newSingleton) {
this.addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
方法的第二個參數(ObjectFactory singletonObject)是Lambda表達式的關鍵,ObjectFactory是個接口,只有一個方法(符合Lambda表達式的要求):
@FunctionalInterface
public interface ObjectFactory<T> {
T getObject() throws BeansException;
}
所以,當getSingleton()方法中執行到:
singletonObject = singletonFactory.getObject();
這一行時,getObject()的實現代碼就是Lambda表達式中的內容,也就是:
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
其中調用了this.createBean()方法。
|----|----|----|----|----|createBean
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getSingleton(beanName, singletonFactory)—createBean
createBean()這個方法在AbstractBeanFactory類中沒有,實際上是由DefaultListableBeanFactory的父類AbstractAutowireCapableBeanFactory來實現的:
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean '" + beanName + "'");
}
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);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
首先調用this.resolveBeanClass()方法,從RootBeanDefinition中獲得了class,如果RootBeanDefinition中沒有class,則需要新建一個。
調用RootBeanDefinition的prepareMethodOverrides()方法,處理這個類裏用@override註解標識的方法,如果方法是不可被重寫的,比如實現的接口裏壓根沒有這個方法,則拋出異常。這個功能貌似現在的常用的IDE都能直接識別出來。
|----|----|----|----|----|----|doCreateBean
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getSingleton(beanName, singletonFactory)—createBean—doCreateBean
後面的
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
是生成這個註解對象的方法,方法代碼如下:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
Object var7 = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
|----|----|----|----|----|----|----|createBeanInstance獲得instanceWrapper
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getSingleton(beanName, singletonFactory)—createBean—doCreateBean—createBeanInstance獲得instanceWrapper
通過調用
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
方法,得到了一個BeanWrapper,BeanWrapper是Spring的屬性包裝器,用來給生成好的對象添加屬性。
this.createBeanInstance()方法如下:
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 new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else {
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
Object var8 = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args) ? this.instantiateBean(beanName, mbd) : this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
}
最開始的
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
是獲得目標對象的class方法,其實就是從mbd中獲得class,方法傳入的className參數是在拋異常的時候寫異常信息用的。
後面判斷這個類是不是public的,如果不是則拋異常。
最後的
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
看起來是獲得類的構造的數組,但是這裏沒看懂,以爲這裏返回構造的數組的肯定是null,因爲this.determineConstructorsFromBeanPostProcessors()方法是這樣的:
@Nullable
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName) throws BeansException {
if (beanClass != null && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var3 = this.getBeanPostProcessors().iterator();
while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
這個方法從所有的BeanPostProcessors中搜尋實現了SmartInstantiationAwareBeanPostProcessor接口的BeanPostProcessor,並調用他的determineCandidateConstructors()方法來得到構造列表。
有好幾個BeanPostProcessor實現了該接口:
比如ImortAwareBanPostProcessor類,這個類是ConfigurationClassPostProcesor類中的內部類,而這個類的determineCandidateConstructors方法是在他的父類InstantiationAwareBeanPostProcessorAdapter中實現的,並且這個方法是這樣的:
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
直接返回null,沒看懂這個方法的存在有什麼意義。
另外還有AutowiredAnnotationBeanPostProcessor,他的determineCandidateConstructors方法是這樣的:
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) throws BeanCreationException {
if (!this.lookupMethodsChecked.contains(beanName)) {
try {
ReflectionUtils.doWithMethods(beanClass, (method) -> {
Lookup lookup = (Lookup)method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
LookupOverride override = new LookupOverride(method, lookup.value());
try {
RootBeanDefinition mbd = (RootBeanDefinition)this.beanFactory.getMergedBeanDefinition(beanName);
mbd.getMethodOverrides().addOverride(override);
} catch (NoSuchBeanDefinitionException var6) {
throw new BeanCreationException(beanName, "Cannot apply @Lookup to beans without corresponding bean definition");
}
}
});
} catch (IllegalStateException var21) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", var21);
}
this.lookupMethodsChecked.add(beanName);
}
Constructor<?>[] candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Map var4 = this.candidateConstructorsCache;
synchronized(this.candidateConstructorsCache) {
candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor[] rawCandidates;
try {
rawCandidates = beanClass.getDeclaredConstructors();
} catch (Throwable var20) {
throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", var20);
}
List<Constructor<?>> candidates = new ArrayList(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
Constructor[] var11 = rawCandidates;
int var12 = rawCandidates.length;
int var13 = 0;
while(true) {
if (var13 >= var12) {
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
} else if (candidates.size() == 1 && this.logger.isWarnEnabled()) {
this.logger.warn("Inconsistent constructor declaration on bean with name '" + beanName + "': single autowire-marked constructor flagged as optional - this constructor is effectively required since there is no default constructor to fall back to: " + candidates.get(0));
}
}
candidateConstructors = (Constructor[])candidates.toArray(new Constructor[0]);
} else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
candidateConstructors = new Constructor[]{rawCandidates[0]};
} else if (nonSyntheticConstructors == 2 && primaryConstructor != null && defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor[]{primaryConstructor, defaultConstructor};
} else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor[]{primaryConstructor};
} else {
candidateConstructors = new Constructor[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
break;
}
label133: {
Constructor<?> candidate = var11[var13];
if (!candidate.isSynthetic()) {
++nonSyntheticConstructors;
} else if (primaryConstructor != null) {
break label133;
}
AnnotationAttributes ann = this.findAutowiredAnnotation(candidate);
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = this.findAutowiredAnnotation(superCtor);
} catch (NoSuchMethodException var19) {
;
}
}
}
if (ann != null) {
if (requiredConstructor != null) {
throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + candidate + ". Found constructor with 'required' Autowired annotation already: " + requiredConstructor);
}
boolean required = this.determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + candidates + ". Found constructor with 'required' Autowired annotation: " + candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
} else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
++var13;
}
}
}
}
return candidateConstructors.length > 0 ? candidateConstructors : null;
}
這個BeanPostProcessor處理的是註解的類裏有Autowired屬性時的處理方法,在這個方法裏對Autowired的required參數進行了判斷。
總之回到AbstractAutowireCapableBeanFactory的createBeanInstance()方法,得到的構造列表,如果得到的構造列表是null,則要調用this.instantiateBean()方法:
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(() -> {
return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this);
}, this.getAccessControlContext());
} else {
beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
this.initBeanWrapper(bw);
return bw;
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
}
}
以此來得到BeanWrapper,首先調用了this.getInstantiationStrategy().instantiate()方法,this.getInstantiationStrategy()是由CglibSubclassingInstantiationStrategy實現的InstantiationStrategy接口,實際上是用cglib構造了一個對目標類的代理。
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
創建了BeanWrapper,傳入的beanInstance保存到BeanWrapper中的wrappedObject屬性。
this.initBeanWrapper(bw);
該方法對BeanWrapper進行了一些初始化,註冊了各種屬性類型的編輯器。然後返回該BeanWrapper。
然後就可以回到AbstractAutowireCapableBeanFactory的doCreateBean()方法,在得到了BeanWrapper後,分被調用了
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
和
this.populateBean(beanName, mbd, instanceWrapper);
兩個方法對bean進行裝配,實際上是從BeanPostProcessor列表中分別選取了不同類型的BeanPostProcessor並調用對應的方法。
|----|----|----|----|----|----|----|initializeBean
當前位置:SpringApplication啓動—refreshContext—finishBeanFactoryInitialization—doGetBean—getSingleton(beanName, singletonFactory)—createBean—doCreateBean—initializeBean
然後調用以下代碼:
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
對bean進行初始化,this.initializeBean()方法代碼如下:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareMethods(beanName, bean);
return null;
}, this.getAccessControlContext());
} 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 (Throwable var6) {
throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
其中
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
這個方法初始化了bean中的一些屬性是bean初始化前的處理方法,方法代碼如下:
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 beanProcessor = (BeanPostProcessor)var4.next();
current = beanProcessor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
}
return result;
}
對BeanPostProcessor列表中的每個BeanPostProcessor都調用postProcessBeforeInitialization()方法,代表在初始化前的處理。
比如dubbo的AnnotationBean這個BeanPostProcessor,他的postProcessBeforeInitialization()方法如下:
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!this.isMatchPackage(bean)) {
return bean;
} else {
Method[] methods = bean.getClass().getMethods();
Method[] arr$ = methods;
int len$ = methods.length;
int len$;
Reference reference;
Object value;
for(len$ = 0; len$ < len$; ++len$) {
Method method = arr$[len$];
String name = method.getName();
if (name.length() > 3 && name.startsWith("set") && method.getParameterTypes().length == 1 && Modifier.isPublic(method.getModifiers()) && !Modifier.isStatic(method.getModifiers())) {
try {
reference = (Reference)method.getAnnotation(Reference.class);
if (reference != null) {
value = this.refer(reference, method.getParameterTypes()[0]);
if (value != null) {
method.invoke(bean);
}
}
} catch (Throwable var12) {
logger.error("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + var12.getMessage(), var12);
}
}
}
Field[] fields = bean.getClass().getDeclaredFields();
Field[] arr$ = fields;
len$ = fields.length;
for(int i$ = 0; i$ < len$; ++i$) {
Field field = arr$[i$];
try {
if (!field.isAccessible()) {
field.setAccessible(true);
}
reference = (Reference)field.getAnnotation(Reference.class);
if (reference != null) {
value = this.refer(reference, field.getType());
if (value != null) {
field.set(bean, value);
}
}
} catch (Throwable var11) {
logger.error("Failed to init remote service reference at filed " + field.getName() + " in class " + bean.getClass().getName() + ", cause: " + var11.getMessage(), var11);
}
}
return bean;
}
}
該方法首先處理由Reference註解標註的set方法,然後處理由Reference註解標註的屬性,並執行:
value = this.refer(reference, method.getParameterTypes()[0]);
生成set方法參數的代理,然後執行
method.invoke(bean);
將set方法執行,相當於把要set的屬性賦值。
然後處理由Reference註解標註的類的屬性,執行:
value = this.refer(reference, field.getType());
生成屬性的代理,然後執行:
field.set(bean, value);
把屬性的代理注入到對象中。
this.applyBeanPostProcessorsBeforeInitialization()方法執行完成後,執行的是:
this.invokeInitMethods(beanName, wrappedBean, mbd);
這個方法會調用bean的初始化方法,初始化方法是可擴展的,應用比較廣泛,方法代碼如下:
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 (this.logger.isDebugEnabled()) {
this.logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(() -> {
((InitializingBean)bean).afterPropertiesSet();
return null;
}, this.getAccessControlContext());
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} 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,方法最開始判斷了這個bean是否實現了InitializingBean接口,InitializingBean接口只有一個方法afterPropertiesSet(),自定義的Bean如果實現了該接口,則會調用afterPropertiesSet()方法。
2,獲得bean的初始化方法mbd.getInitMethodName(),如果有初始化方法而且這個初始化方法不是afterPropertiesSet(),則調用這個初始化方法。
這個初始化方法可以在配置文件中進行指定,比如這樣:
<bean class="TestService" init-method="methodName"></bean>
經過以上BeanPostProcessor的處理,需要註解生成的類的代理就生成成功了,代碼回到AbstractAutowireCapableBeanFactory的doCreateBean()方法,
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
這一行,得到的exposedObject就是由Spring註解類的代理。
invokeInitMethods()方法完成後,調用的是:
this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
方法代碼是:
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 beanProcessor = (BeanPostProcessor)var4.next();
current = beanProcessor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
}
return result;
}
和之前的applyBeanPostProcessorsBeforeInitialization()方法差不多,還是獲取了所有的BeanPostProcessor,只不過這次調用的是postProcessAfterInitialization()方法。
綜上可以看到,整個initializeBean()方法,正如方法名字一樣,是在bean創建和裝配完成之後的初始化工作,而完成這項工作的這是註冊好的BeanPostProcessor和InitializingBean。BeanPostProcessor接口中定義的:
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
兩個方法,還有InitializingBean接口定義的:
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
一個方法,完成了自定義的AOP功能。
至此initializeBean()方法結束。
doCreateBean()方法結束。
createBean()方法結束。
getSingleton()方法結束。
doGetBean()方法結束。
finishBeanFactoryInitialization()方法結束。
此時的調用棧:
AbstractAutowireCapableBeanFactory.doCreateBean()
AbstractAutowireCapableBeanFactory.createBean()
DefaultListableBeanFactory.getSingleton()
AbstractBeanFactory.doGetBean()
AbstractBeanFactory.getBean()
DefaultListableBeanFactory.preInstantiateSingletons()
AbstractApplicationContext. finishBeanFactoryInitialization()
另外,在doGetBean方法中,除了getSingleton()之外還有另一個分支:當bean配置爲非單例模式時,用另外的方式獲得了bean。在非單例模式下,每次對bean的請求都會新建一個新的實例,Spring不會強制管理這個bean的生命週期,一般要由開發者控制。
此時AbstractApplicationContext.refresh()方法中
this.finishBeanFactoryInitialization(beanFactory);
這行代碼執行完成,基本生成了需要控制反轉的類的代理。
|----|----|finishRefresh
當前位置:SpringApplication啓動—refreshContext—finishRefresh
最後是AbstractApplicationContext.refresh()方法中的
this.finishRefresh();
這裏有個小坑,此時執行方法的bean是AnnotationConfigServletWebServerApplicationContext,所以此時執行的finishRefresh()方法不在AbstractApplicationContext類中,而是在AnnotationConfigServletWebServerApplicationContext的父類ServletWebServerApplicationContext中。另外,AbstractApplicationContext是ServletWebServerApplicationContext的父類。
ServletWebServerApplicationContext的finishRefresh()方法:
protected void finishRefresh() {
super.finishRefresh();
WebServer webServer = this.startWebServer();
if (webServer != null) {
this.publishEvent(new ServletWebServerInitializedEvent(webServer, this));
}
}
方法第一行的super.finishRefresh();這次執行的是AbstractApplicationContext類中的finishRefresh()方法了,方法代碼是:
protected void finishRefresh() {
this.clearResourceCaches();
this.initLifecycleProcessor();
this.getLifecycleProcessor().onRefresh();
this.publishEvent((ApplicationEvent)(new ContextRefreshedEvent(this)));
LiveBeansView.registerApplicationContext(this);
}
清空了Resource緩存。
向BeanFactory中註冊了LifecycleProcessor,實際上由DefaultLifecycleProcessor實現。
調用LifecycleProcessor的onRefresh()方法,實際上調用DefaultLifecycleProcessor的onRefresh()方法:
public void onRefresh() {
this.startBeans(true);
this.running = true;
}
這個onRefresh()方法的作用基本上是準備啓動之前的TomcatWebServer,其中this.startBeans(true)方法的代碼:
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = this.getLifecycleBeans();
Map<Integer, DefaultLifecycleProcessor.LifecycleGroup> phases = new HashMap();
lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || bean instanceof SmartLifecycle && ((SmartLifecycle)bean).isAutoStartup()) {
int phase = this.getPhase(bean);
DefaultLifecycleProcessor.LifecycleGroup group = (DefaultLifecycleProcessor.LifecycleGroup)phases.get(phase);
if (group == null) {
group = new DefaultLifecycleProcessor.LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly);
phases.put(phase, group);
}
group.add(beanName, bean);
}
});
if (!phases.isEmpty()) {
List<Integer> keys = new ArrayList(phases.keySet());
Collections.sort(keys);
Iterator var5 = keys.iterator();
while(var5.hasNext()) {
Integer key = (Integer)var5.next();
((DefaultLifecycleProcessor.LifecycleGroup)phases.get(key)).start();
}
}
}
this.startBeans(true)方法執行結束後,AbstractApplicationContext的this.publishEvent()方法就結束了,然後執行的是AbstractApplicationContext的:
LiveBeansView.registerApplicationContext(this);
registerApplicationContext()方法的代碼如下:
static void registerApplicationContext(ConfigurableApplicationContext applicationContext) {
String mbeanDomain = applicationContext.getEnvironment().getProperty("spring.liveBeansView.mbeanDomain");
if (mbeanDomain != null) {
Set var2 = applicationContexts;
synchronized(applicationContexts) {
if (applicationContexts.isEmpty()) {
try {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
applicationName = applicationContext.getApplicationName();
server.registerMBean(new LiveBeansView(), new ObjectName(mbeanDomain, "application", applicationName));
} catch (Throwable var5) {
throw new ApplicationContextException("Failed to register LiveBeansView MBean", var5);
}
}
applicationContexts.add(applicationContext);
}
}
}
該方法從環境變量中獲取了spring.liveBeansView.mbeanDomain參數,然後向PlatformMBeanServer裏註冊了一個LiveBeansView對象。
至此AbstractApplicationContext的finishRefresh()方法結束。
回到ServletWebServerApplicationContext的finishRefresh()方法,
super.finishRefresh();
方法結束。
|----|----|----|startWebServer
當前位置:SpringApplication啓動—refreshContext—finishRefresh—startWebServer
下面的
WebServer webServer = this.startWebServer();
其中startWebServer()方法的代碼如下:
public void start() throws WebServerException {
Object var1 = this.monitor;
synchronized(this.monitor) {
if (!this.started) {
boolean var10 = false;
try {
var10 = true;
this.addPreviouslyRemovedConnectors();
Connector var2 = this.tomcat.getConnector();
if (var2 != null && this.autoStart) {
this.startConnector();
}
this.checkThatConnectorsHaveStarted();
this.started = true;
logger.info("Tomcat started on port(s): " + this.getPortsDescription(true) + " with context path '" + this.getContextPath() + "'");
var10 = false;
} catch (ConnectorStartFailedException var11) {
this.stopSilently();
throw var11;
} catch (Exception var12) {
throw new WebServerException("Unable to start embedded Tomcat server", var12);
} finally {
if (var10) {
Context context = this.findContext();
ContextBindings.unbindClassLoader(context, context.getNamingToken(), this.getClass().getClassLoader());
}
}
Context context = this.findContext();
ContextBindings.unbindClassLoader(context, context.getNamingToken(), this.getClass().getClassLoader());
}
}
}
和之前tomcat啓動不同,這裏啓動的是connector,正式啓動這個webServer。
webServer啓動後,調用了
this.publishEvent(new ServletWebServerInitializedEvent(webServer, this));
publishEvent()方法的代碼在AbstractApplicationContext中:
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
Assert.notNull(event, "Event must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Publishing event in " + this.getDisplayName() + ": " + event);
}
Object applicationEvent;
if (event instanceof ApplicationEvent) {
applicationEvent = (ApplicationEvent)event;
} else {
applicationEvent = new PayloadApplicationEvent(this, event);
if (eventType == null) {
eventType = ((PayloadApplicationEvent)applicationEvent).getResolvableType();
}
}
if (this.earlyApplicationEvents != null) {
this.earlyApplicationEvents.add(applicationEvent);
} else {
this.getApplicationEventMulticaster().multicastEvent((ApplicationEvent)applicationEvent, eventType);
}
if (this.parent != null) {
if (this.parent instanceof AbstractApplicationContext) {
((AbstractApplicationContext)this.parent).publishEvent(event, eventType);
} else {
this.parent.publishEvent(event);
}
}
}
至此ServletWebServerApplicationContext的finishRefresh()方法執行結束
AbstractApplicationContext的refresh()方法結束
ServletWebServerApplicationContext的refresh()方法結束
SpringApplication的refresh()方法結束
SpringApplication的refreshContext()方法的this.refresh(context);執行結束
重新貼一下SpringApplication的refreshContext()方法:
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException var3) {
;
}
}
}
|----|----|registerShutdownHook
當前位置:SpringApplication啓動—refreshContext—registerShutdownHook
this.refresh(context);執行結束後,調用了
context.registerShutdownHook();
此處的context是AnnotationConfigServletWebServerApplicationContext,他的registerShutdownHook()方法在父類AbstractApplicationContext中:
public void registerShutdownHook() {
if (this.shutdownHook == null) {
this.shutdownHook = new Thread() {
public void run() {
synchronized(AbstractApplicationContext.this.startupShutdownMonitor) {
AbstractApplicationContext.this.doClose();
}
}
};
Runtime.getRuntime().addShutdownHook(this.shutdownHook);
}
}
添加了一個關閉用的鉤子。
至此SpringApplication的refreshContext()方法執行結束
SpringApplication的run()方法執行完了this.refreshContext(context);這一行。
重新貼一下SpringApplication的run()方法:
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
執行完
this.refreshContext(context);
後,執行的是
this.afterRefresh(context, applicationArguments);
這是個空方法。
|----|listeners start
當前位置:SpringApplication啓動—listeners start
後面的
listeners.started(context);
方法的代碼:
public void started(ConfigurableApplicationContext context) {
Iterator var2 = this.listeners.iterator();
while(var2.hasNext()) {
SpringApplicationRunListener listener = (SpringApplicationRunListener)var2.next();
listener.started(context);
}
}
這裏的Linstener由EventPublishingRunListener實現,調用了他的started方法,實際上是發送了一個ApplicationStartedEvent的事件。
|----|callRunners
當前位置:SpringApplication啓動—callRunners
接下來是調用
this.callRunners(context, applicationArguments);
方法代碼是:
private void callRunners(ApplicationContext context, ApplicationArguments args) {
List<Object> runners = new ArrayList();
runners.addAll(context.getBeansOfType(ApplicationRunner.class).values());
runners.addAll(context.getBeansOfType(CommandLineRunner.class).values());
AnnotationAwareOrderComparator.sort(runners);
Iterator var4 = (new LinkedHashSet(runners)).iterator();
while(var4.hasNext()) {
Object runner = var4.next();
if (runner instanceof ApplicationRunner) {
this.callRunner((ApplicationRunner)runner, args);
}
if (runner instanceof CommandLineRunner) {
this.callRunner((CommandLineRunner)runner, args);
}
}
}
該方法查詢出了context中的ApplicationRunner和CommandLineRunner,並通過this.callRunner()方法調用了他們的run()方法。
不過默認情況下context中沒有這兩種Runner,需要自己定義,實現接口並重寫run()方法,當代碼運行到這裏時,上下文的基本裝配工作已經完成了,所以重寫的run()方法代碼可以起到開機自啓動的效果。
這兩種Runner功能基本相同,使用的參數略有區別,ApplicationRunner的run()方法中可以使用
args.getOptionNames()
獲得java啓動命令中的參數key數組。
args.getOptionValues("xxx")
獲得java啓動命令中某個參數的value。
|----|listeners running
當前位置:SpringApplication啓動—listeners running
接下來是調用
listeners.running(context);
和前面的listeners.started()方法一樣,發佈了一個running事件。
該方法執行完成後,SpringApplication的run(String... args)方法執行結束。
SpringApplication的run(Class<?>[] primarySources, String[] args)方法執行結束。
SpringApplication的run(Class<?> primarySource, String... args)方法執行結束。
代碼開始的
SpringApplication.run(TestApplication.class, args);
執行結束。
Spring-boot的ApplicationContext啓動結束
終於結束了,以上是Spring-boot啓動的大概流程,對於很多代碼細節,模塊功能,設計模式,都還理解不了,留待以後慢慢研究。