.SpringBoot 源码执行流程图
2. 创建SpringApplication 应用,在构造函数中推断启动应用类型,并进行spring boot自动装配
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
查看 SpringApplication 构造函数
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.sources = new LinkedHashSet();
// 获取banner打印模式
this.bannerMode = Mode.CONSOLE;
this.logStartupInfo = true;
// 添加命令行系统属性
this.addCommandLineProperties = true;
this.addConversionService = true;
this.headless = true;
this.registerShutdownHook = true;
this.additionalProfiles = Collections.emptySet();
this.isCustomEnvironment = false;
// 是否懒加载
this.lazyInitialization = false;
// 默认赋值 applicationContextFactory 工厂对象
this.applicationContextFactory = ApplicationContextFactory.DEFAULT;
this.applicationStartup = ApplicationStartup.DEFAULT;
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet(Arrays.asList(primarySources));
// 根据类加载路径推断webApplicaitonType类型:SERVLET;REACTIVE
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 进行Spring的自动装配,主要用来SpringFactoriesLoader类进行装载工厂
this.bootstrappers = new ArrayList(this.getSpringFactoriesInstances(Bootstrapper.class));
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 设置监听器
this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = this.deduceMainApplicationClass();
}
getSpringFactoriesInstances 方法主要用来进行Spring的自动装配;用 SpringFactoriesLoader类 进行装载工厂,工厂资源位于 META-INF/spring.factories 文件中,这个文件可能在类路径的多个jar文件中。然后调用createSpringFactoriesInstances() 方法对工厂进行实例化并根据注解进行排序。
3.SpringApplication.run方法源码
查看run方法源码
public ConfigurableApplicationContext run(String... args) {
// 应用启动计时器
StopWatch stopWatch = new StopWatch();
stopWatch.start();
DefaultBootstrapContext bootstrapContext = this.createBootstrapContext();
// 初始化应用上下文
ConfigurableApplicationContext context = null;
this.configureHeadlessProperty();
// 获取启动监听器
SpringApplicationRunListeners listeners = this.getRunListeners(args);
//监听器使用类似于生产-消费模式进行消息监听
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
//构建应用参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
//准备应用环境
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, bootstrapContext, applicationArguments);
this.configureIgnoreBeanInfo(environment);
//打印banner
Banner printedBanner = this.printBanner(environment);
//创建ApplicationContext
context = this.createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
//准备context
this.prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
//重点:刷新context:实现IOC容器启动的整个过程
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, listeners);
throw new IllegalStateException(var10);
}
}
获取启动监听器。实际上获取的是一个EventPublishingRunListener对象,这个类能通过一个SimpleApplicationEventMulticaster对象广播事件,用到了Executor多线程异步执行框架;
3.1 执行prepareEnvironment 方法,准备应用环境
prepareEnvironment 方法源码
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
// 根据前面推断的web环境类型创建推Environment对象
ConfigurableEnvironment environment = this.getOrCreateEnvironment();
// 进行环境配置
this.configureEnvironment((ConfigurableEnvironment)environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach((Environment)environment);
listeners.environmentPrepared(bootstrapContext, (ConfigurableEnvironment)environment);
DefaultPropertiesPropertySource.moveToEnd((ConfigurableEnvironment)environment);
this.configureAdditionalProfiles((ConfigurableEnvironment)environment);
this.bindToSpringApplication((ConfigurableEnvironment)environment);
if (!this.isCustomEnvironment) {
environment = (new EnvironmentConverter(this.getClassLoader())).convertEnvironmentIfNecessary((ConfigurableEnvironment)environment, this.deduceEnvironmentClass());
}
ConfigurationPropertySources.attach((Environment)environment);
return (ConfigurableEnvironment)environment;
}
prepareEnvironment 方法主要用来准备应用环境,进行property配置文件解析,profile 环境解析以及获取系统属性和系统环境等;
3.1.1 getOrCreateEnvironment 方法源码
private ConfigurableEnvironment getOrCreateEnvironment() {
if (this.environment != null) {
return this.environment;
} else {
switch(this.webApplicationType) {
case SERVLET:
return new StandardServletEnvironment();
case REACTIVE:
return new StandardReactiveWebEnvironment();
default:
return new StandardEnvironment();
}
}
}
StandardEnvironment的构造器会先对属性源进行定制(将系统属性和系统环境添加到一个MutablePropertySources维护的list中)。这个对象的主要工作包括property分析、profile相关操作、获取系统属性和系统环境等。
3.1.2 configureEnvironment() 方法获取配置环境
configureEnvironment() 源码:
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
environment.setConversionService((ConfigurableConversionService)conversionService);
}
// 配置属性源
this.configurePropertySources(environment, args);
//获取激活的 profile
this.configureProfiles(environment, args);
}
configureProfiles 方法通过AbstractEnvironment#getActiveProfiles() 解析 spring.profile.active 属性,添加到activeProfiles这个集合中。
3.2.createApplicationContext方法
createApplicationContext 方法源码
protected ConfigurableApplicationContext createApplicationContext() {
return this.applicationContextFactory.create(this.webApplicationType);
}
进入 applicationContextFactory.create 方法的类中,存在一个根据webApplicationType获取容器类型的变量方法如下:
@FunctionalInterface
public interface ApplicationContextFactory {
// 根据webApplicationType返回指定的容器实例
applicationContextFactoryApplicationContextFactory DEFAULT = (webApplicationType) -> {
try {
switch(webApplicationType) {
case SERVLET:
return new AnnotationConfigServletWebServerApplicationContext();
case REACTIVE:
return new AnnotationConfigReactiveWebServerApplicationContext();
default:
return new AnnotationConfigApplicationContext();
}
} catch (Exception var2) {
throw new IllegalStateException("Unable create a default ApplicationContext instance, you may need a custom ApplicationContextFactory", var2);
}
};
ConfigurableApplicationContext create(WebApplicationType webApplicationType);
}
通过以上方式获取到具体的ApplicationContext实例,并通过构造函数进行实例化,查看构造函数的过程:
3.2.1AnnotationConfigApplicationContext() 的构造方法
构造方法源码如下:
public AnnotationConfigApplicationContext() {
// 启动上面获取的容器类型实例
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 构建AnnotatedBeanDefinitionReader对象
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 构建 ClassPathBeanDefinitionScanner对象
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
AnnotationConfigApplicationContext的默认构造器会构造一个AnnotationBeanDefinitionReader对象和ClassPathBeanDefinitionScanner对象,在构造AnnotationBeanDefinitionReader对象的过程中会向bean factory添加注解处理器和事件监听处理器BeanDefinition,为后续的配置解析作准备。这样,就能通过JavaConfig 构建 BeanDefinition 并实现自动扫描。
AnnotationConfigApplicationContext的父类GenericApplicationContext的默认构造器会构造一个DefaultListableBeanFactory 对象,这样应用上下文持有一个bean factory的引用,大部分应用只需与应用上下文提供的接口打交道就是因为它对bean factory进行了一层封装。至此,一个Spring容器已经构造出来了,但是目前这个容器还什么都没有,需要根据用户的配置文件进行配置才能按照用户逻辑进行工作。
3.3.prepareContext方法
prepareContext 方法源码
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
// 使context持有应用环境的引用,同时将应用环境的引用赋给reader和scanner
context.setEnvironment(environment);
// 实现应用上下文的后置处理:主要是注册BeanNameGenerator类型的bean并设置应用上下文的资源加载器和类加载器
this.postProcessApplicationContext(context);
// 应用初始化器--添加监听器、logger、warnning、以及spring启动加解密等组件
this.applyInitializers(context);
listeners.contextPrepared(context);
bootstrapContext.close(context);
if (this.logStartupInfo) {
this.logStartupInfo(context.getParent() == null);
this.logStartupProfileInfo(context);
}
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 添加启动相关的bean
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
// 注册打印banner的bean
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
// 注册可定义重写的bean
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory)beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 添加懒加载的bean工厂后置处理器
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
Set<Object> sources = this.getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 重点:将source bean装载到应用上下文
this.load(context, sources.toArray(new Object[0]));
// 日志配置
listeners.contextLoaded(context);
}
该方法主要进行 context 添加初始化器,包括监听器、logger、warnning、以及spring启动加解密组件等等;并设置一些启动需要的 bean;
通过 load 方法将所有的bean注册到 容器中;该方法实现的调用链如下:
SpringApplication.load(ApplicationContext context, Object[] sources)-------->
BeanDefinitionLoader.load()---->BeanDefinitionLoader.load(Object source)--->
BeanDefinitionLoader.load(Class<?> source)----->AnnotatedBeanDefinitionReader.register(Class<?>... componentClasses)--->
AnnotatedBeanDefinitionReader.registerBean(Class<?> beanClass)---->
AnnotatedBeanDefinitionReader.doRegisterBean --->
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
需要关注 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry) 这个操作;继续跟进这个方法的具体实现,会发现所有的 bean 注册都是保存在一个map中,比如DefaultListableBeanFactory 类中的registerBeanDefinition 方法是将bean保存到自定义的map集合中
private final Map<String, BeanDefinition> beanDefinitionMap;
3.4 refreshContext中refresh方法
查看refreshContext 中 refresh 方法源码
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 为应用上下文的刷新做准备--设置时间、记录刷新日志、初始化属性源中的占位符和验证必要的属性等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 使用CAS让子类刷新内部的bean factory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备在这个应用上下文中使用的bean factory
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// bean factory 后置处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用应用上下文中作为bean注册的工厂处理器
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册拦截创建bean的bean处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化消息源
initMessageSource();
// Initialize event multicaster for this context.
// 初始化事件广播
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 初始化特定上下文子类中的其它bean
onRefresh();
// Check for listener beans and register them.
// 注册监听器bean
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有的单例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发布相应的事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
3.4.1 prepareRefresh()
AbstractApplicationContext#prepareRefresh() 源码:
protected void prepareRefresh() {
//记录启动时间
this.startupDate = System.currentTimeMillis();
//标志位设置
this.closed.set(false);
this.active.set(true);
//日志记录一下
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
// 初始化资源占位符
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
// 验证所有必要的属性能通过getProperty()解析,不能则抛出异常
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
创建environment并加载System.properties()及System.getenv()到environment中
3.4.2 obtainFreshBeanFactory()
因为AbstractApplication没有引用bean factory,只定义了刷新bean factory相关的方法,刷新bean factory的具体实现在子类的GenericApplicationContext#refreshBeanFactory()中实现,具体代码和说明如下:
protected final void refreshBeanFactory() throws IllegalStateException {
// 只支持刷新一次
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException("GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
// 设置序列号
this.beanFactory.setSerializationId(getId());
}
可以看到对bean factory的刷新实际上只是为其设置了一个序列号。
3.4.3 prepareBeanFactory()
AbstractApplicationContext#prepareBeanFactory()。这个方法比较长,主要做的工作是对bean factory进行一些设置并添加一些辅助bean,具体代码和说明如下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 使用应用上下文的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置bean表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加属性编辑器注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this,getEnvironment()));
// Configure the bean factory with context callbacks.
// 使用上下文回调函数配置bean factory
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 注册依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
// 添加一个用于探测实现了ApplicationListener接口的bean的后置处理器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 探测LoadTimeWeaver并准备织入,与AOP相关
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 将默认环境作为bean注册
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
addBeanPostProcessor()会添加一个ApplicationContextAwareProcessor处理器,这个类实现了BeanPostProcessor接口,同时由于应用上下文持有其它*Aware等的引用,因此在后面的代码中忽略了这些依赖
3.4.4 invokeBeanFactoryPostProcessors()
该方法会扫描到指定包下标有注解的类,然后将其变成BeanDefinition对象,然后放到一个Spring的Map中,用于后面创建Spring bean的时候使用这个BeanDefinition
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// BeanFactory后置处理器的具体实现
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
Spring委托PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors实现后置处理,它的具体实现很长,系统启动时就注册了几个后置处理器,如SharedMetadataReaderFactoryContextInitializer,CachingMetadataReaderFactoryPostProcessor等。
代码的执行思路是:先将后置处理器进行分类,分别是BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,同时将BeanDefinitionRegistry注册为一个BeanDefinition并调用注册表后置处理器的相关方法(与注册表相关);接着,按PriorityOrdered, Ordered和其它的顺序调用手动添加(Spring Boot)的后置处理器。Spring Boot在之前注册过一个ConfigurationClassPostProcessor后置处理器;
最终这个后置处理器会调用ConfigurationClassPostProcessor#processConfigBeanDefinitions()对配置类进行处理。在处理时需要创建 ConfigurationClassParser对象进行解析,同时会创建一个 ComponentScanAnnotationParser 对象,在这个类中会扫描获取所有带有注解的bean类;
ConfigurationClassPostProcessor#processConfigBeanDefinitions()具体的思路是先获取所有的bean definition,并找出配置类对应的bean definition。接着对容器进行一下转换并实例化一个ConfigurationClassParser配置类解析器对象parser,调用parser的parse()对配置类进行解析。ConfigurationClassParser#parse()的具体实现如下:
public void parse(Set<BeanDefinitionHolder> configCandidates) {
this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
//如果bean是注解的,则解析注解---Spring Boot基于注解配置
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
// 如果是抽象bean并且有bean类
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
} else {
// 普通解析
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanDefinitionStoreException( "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
// 处理延迟导入的选择器
processDeferredImportSelectors();
}
在处理配置bean时,ConfigurationClassParser#doProcessConfigurationClass()会首先迭代地处理所有嵌套的配置类,然后处理所有的@PropertySource注解来解析属性源,再处理@ComponentScan注解实现自动扫描,再处理@Import注解来导入配置类,注意,@SpringBootApplication注解由@EnableAutoConfiguration注解,而@EnableAutoConfiguration由@Import(EnableAutoConfigurationImportSelector.class)注解,同时它的@AutoConfigurationPackage由@Import(AutoConfigurationPackages.Registrar.class)注解,从这里可以看到@EnableAutoConfiguration默认导入了两个类。
对@ImportResource注解的处理
处理@Bean注解的方法不会注册bean,只在配置类中注册相应的方法。
处理超类
processDeferredImportSelectors()的具体实现:
private void processDeferredImportSelectors() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);
for (DeferredImportSelectorHolder deferredImport : deferredImports) {
ConfigurationClass configClass = deferredImport.getConfigurationClass();
try {
// 获取importSelector---在自动配置源数据中删除不符合要求或者无法实例化的对象
String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
//处理import---迭代处理,最终调用processConfigurationClass处理自动配置的类
processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" + configClass.getMetadata().getClassName() + "]", ex);
}
}
}
至此,Spring Boot的自动配置基本完成
3.4.5 registerBeanPostProcessors()
根据实现了PropertyOrdered,Order接口,排序后注册所有的BeanPostProcessor后置处理器,主要用于创建bean时,执行这些后置处理器的方法,这也是Spring 提供的扩展点,让我们能够插手Spring bean的创建过程。
3.4.6 重点 finishBeanFactoryInitialization() 实现SpringBean生命周期过程
完成所所有单例bean的创建和实例化,其方法调用链如下
AbstractApplicationContext.finishBeanFactoryInitialization(方法最后一行)-----〉
AbstractBeanFactory.getBean---->AbstractBeanFactory.doGetBean------->
AbstractAutowireCapableBeanFactory.createBean------->
重点:AbstractAutowireCapableBeanFactory.doCreateBean(这个方法进行bean的生命周期)
在实例化Bean的过程中,会按照顺序执行,如下:
resolveBeforeInstantiation会找到类型为InstantiationAwareBeanPostProcessor,且在Bean初始化前对Bean执行操作,实例化 ----》 AbstractAutowireCapableBeanFactory.doCreateBean() populateBean注入属性initalizeBean方法调用扩展,顺序如下:
1)如果Bean是BeanNameAware,BeanClassLoaderAware,BeanFactoryAware,会执行者几个的方法Aware的对应方法
2)先执行所有BeanPostProcessor.postProcessBeforeInitialization()
3) 反射调用init方法,如果Bean是InitializingBean,会先执行InitializingBean的afterPropertiesSet方法, 然后在执行自动以的init方法 、
4)调用所有BeanPostProcessor.applyBeanPostProcessorsAfterInitialization()方法 @PostConstruct标记的方法,是在BeanPostProcessor.postProcessBeforeInitialization() 调用时执行,也就是有一个BeanPostProcessor用于处理标记了该注解的方法(InitDestroyAnnotationBeanPostProcessor),定时器等注解,原理也是一样的,在解析BeanDefinition时,会将这些注解都解析成BeanDefinition的一个属性
bean生命周期执行过程图如下:
可以简述为以下九步
- 实例化bean对象(通过构造方法或者工厂方法)
- 设置对象属性(setter等)(依赖注入)
- 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)
- 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
- 将Bean实例传递给Bean的前置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法
- 调用Bean的初始化方法; Spring检测对象如果实现InitializingBean这个接口,就会执行他的afterPropertiesSet()方法,定制初始化逻辑。以及进行@PostConstruct注解逻辑实现
- 将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法
- 使用Bean
- 容器关闭之前,调用Bean的销毁方法
文章来自https://www.cnblogs.com/zjdxr-up/p/16219720.html
本文暂时没有评论,来添加一个吧(●'◡'●)