前言:
文章很长,一万多字,如果不关注细节的话只看目录就可以。
目录设置了缩进,代表了启动流程中方法的调用和包含关系。
目录基本上概述了SpringBoot启动的基本流程。
目录
main方法启动
初始化SpringApplication
|----|设置ApplicationContextInitializer和ApplicationListener
|----|----|读取配置中的Name
|----|----|根据Name初始化Initializer和Linstener的实例
SpringApplication启动
|----|设置并启动SpringApplicationRunListener
|----|生成ApplicationContext对象
|----|prepareContext
|----|----|Initializer初始化
|----|refreshContext
|----|----|postProcessBeanFactory
|----|----|----|初始化BeanFactory的BeanDefinition
|----|----|----|BeanDefinition注册
|----|----|registerBeanPostProcessors分类注册
|----|----|initMessageSource初始化信息源
|----|----|initApplicationEventMulticaster初始化事件广播器
|----|----|onRefresh
|----|----|----|createWebServer
|----|----|----|----|tomcat启动
|----|----|registerListeners
|----|----|finishBeanFactoryInitialization
|----|----|----|doGetBean
|----|----|----|----|getSingleton(beanName)和循环依赖的处理
|----|----|----|----|getMergedLocalBeanDefinition
|----|----|----|----|getSingleton(beanName, singletonFactory)
|----|----|----|----|----|createBean
|----|----|----|----|----|----|doCreateBean
|----|----|----|----|----|----|----|createBeanInstance获得instanceWrapper
|----|----|----|----|----|----|----|initializeBean
|----|----|finishRefresh
|----|----|----|startWebServer
|----|----|registerShutdownHook
|----|listeners start
|----|callRunners
|----|listeners running
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启动的大概流程,对于很多代码细节,模块功能,设计模式,都还理解不了,留待以后慢慢研究。