读完这章,你还敢说你不会SpringBoot源码?
Posted 守夜人爱吃兔子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了读完这章,你还敢说你不会SpringBoot源码?相关的知识,希望对你有一定的参考价值。
前言
笔者把之前的Spring的格式重新排版,并且细致到一行一个讲解,希望大家喜欢。
大家使用Spring Boot这么久了,有没有知道Spring Boot的启动流程是怎样的呢?Spring是如何扫描到使用@Component的类并且把它放进BeanFactory呢?它是如何启动的呢?现在我们就一起看看。本系列会分几个章节去讲述这个Spring Boot的启动过程。由于写这篇文章的时候,在很多环境写过,所以可能由于Spring Boot版本不同代码也不同,但是思路是一样的。
1.创建SpringApplication对象
// 1.main方法
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
public static void main(String[] args) {
// 启动入口,请点击run方法
SpringApplication.run(DemoApplication.class, args);
}
}
// 2.main方法进来后先创建一个实例new SpringApplication 蹩脚翻译一下
/**
* 创建一个新的SpringApplication实例也就是要new SpringApplication(),并且定义主要的类作为Bean的加载来源
*/
/**
* Create a new {@link SpringApplication} instance. The application context will load
* beans from the specified primary sources (see {@link SpringApplication class-level}
* documentation for details. The instance can be customized before calling
* {@link #run(String...)}.
* @param resourceLoader the resource loader to use
* @param primarySources the primary bean sources
* @see #run(Class, String[])
* @see #setSources(Set)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
// 设置类入口也就是启动类
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 设置这个应用的类型,分别为SERVLET、NONE、REACTIVE。具体可以看WebApplicationType枚举类
this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 设置初始化器,这个getSpringFactoriesInstances()方法是从spring.factories中读取
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 设置监听器,更上面一样也就是只要看到这个方法就是从spring.factories中读取要的类并且加载
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}
2.在SpringApplication对象调用run()
/**
* 1.跑run方法
*/
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
// 开启计时器
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 配置一些外设
configureHeadlessProperty();
// 获取监听器,这个getRunlisteners方法里面也是一样获取监听器
SpringApplicationRunListeners listeners = getRunListeners(args);
// 监听器开始执行
listeners.starting();
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
configureIgnoreBeanInfo(environment);
// 打印banner
Banner printedBanner = printBanner(environment);
// 创建应用上下文,请看2
context = createApplicationContext();
// 加载异常报告期
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// 准备上下文,请看3
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
listeners.started(context);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
/**
* 2.这个方法是从创建SpringApplication实例加载的应用类型去创建不同的上下文实例,这里由于是SERVLET类型所以会创建
*/
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
// org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
// 叫做注解配置上下文实例(蹩脚翻译)
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
/**
* 3.准备上下文,这里其实挺重要的,讲述了启动类如何加载到BeanFactory
* 其实就一个重点,在load()这个方法里面
*/
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
context.setEnvironment(environment);
postProcessApplicationContext(context);
applyInitializers(context);
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
// 这里context因为是AnnotationConfigServletWebServerApplicationContext
// 所以他继承于ServletWebServerApplicationContext
// ServletWebServerApplicationContext继承GenericWebApplicationContext
// GenericWebApplicationContext继承GenericApplicationContext
// 所以他的beanFactory是默认的private final DefaultListableBeanFactory beanFactory;
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 这个方法讲述了启动类如何注册到beanFactory里面,为下面的refreshContext做了铺垫
// 而且这个load方法里面还有启动类如何注册到BeanDefinition里面去的,去看4
load(context, sources.toArray(new Object[0]));
listeners.contextLoaded(context);
}
/**
* 4.这里就先说下doRegisterBean()
* 每个bean被执行doGetBean方法前都是要把Bean的定义信息拿到,也就是通俗的BeanDefinition,类的元数据
* 而AnnotatedGenericBeanDefinition就是为了公开这些类元数据做的接口
* 当adb和beanName一起在BeanDefinitionHolder初始化的时候
*/
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 定义bean的元数据对象,下面都是获取bean名字之类的
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 当元数据对象与beanName创建了BeanDefinitionHolder
// 他会把一些alias和beanName全部保存下来
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 这里就会正式把此bean注册到this.beanDefinitionMap和this.beanDefinitionNames属性里面
// 而这两个属性就是刚刚的默认beanFactory也就是DefaultListableBeanFactory.class
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
3.核心方法refreshContext
/**
* 1.此方法其实就是Spring整个启动过程或者说ioc等等的核心流程了
* 这个方法分几步去讲解
*/
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 准备上下文
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 这个方法是扫描所有的Bean和加载所有的Bean
invokeBeanFactoryPostProcessors(beanFactory);
// 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();
}
}
}
/**
* 2.这里进来就是beanFactory增强器加载
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// getBeanFactoryPostProcessors()这个方法就是获取当前所有的beanFactory增强器进去可以看看,目前默认有3个
// 1.SharedMetadataReaderFactoryContextInitializer$CachingMetadataReaderFactoryPostProcessor在prepareContext中的applyInitializers插入
// 2.ConfigurationWarningsApplicationContextInitializer$ConfigurationWarningsPostProcessor在prepareContext中的applyInitializers插入
// 3.ConfigFileApplicationListener$PropertySourceOrderingPostProcessor在prepareContext最后一行listeners.contextLoaded(context)插入
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()));
}
}
/**
* 3.这方法重中之重,里面包涵了大量的操作我们来一起看看
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 这个context是AnnotationConfigServletWebServerApplicationContext实例他继承的类有BeanDefinitionRegistry接口
// 所以这里一定会进来
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 这个循环是把那3个增强器分类
// CachingMetadataReaderFactoryPostProcessor实现BeanDefinitionRegistryPostProcessor
// ConfigurationWarningsPostProcesso实现BeanDefinitionRegistryPostProcessor
// PropertySourceOrderingPostProcessor实现BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 这里把BeanDefinition注册进去
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 这里获取到的beanName不是刚刚的增强器而是常量org.springframework.context.annotation.internalConfigurationAnnotationProcessor
// 并且下面这个循环会把ConfigurationClassPostProcessor加载出来。
// 那么大家会问ConfigurationClassPostProcessor什么时候加载的呢?
// createApplicationContext这个方法还记得吧!就是在这里加载的当Spring选择了Servlet模式就会加载配置
// CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME就会作为beanNamePut进beanFactory
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 当ConfigurationClassPostProcessor回去跑processConfigBeanDefinitions方法,跳去4
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
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();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
/**
* 4.这里就是把启动类选出来并且开始ComponentScan的地方,自动装配也是这里完成的@Import
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
//configCandidates这会加入启动类
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
/**
* 省略代码
*/
// Parse each @Configuration class
// 这就是找Component的实现类
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 这个是重点parse有很多Component类这里用来
parser.parse(candidates);
/**
* 省略代码
*/
}
while (!candidates.isEmpty());
/**
* 省略代码
*/
}
/**
* 5.扫描Component和自动装配,这个也很重要,而且段代码有几个递归也是比较复杂
* 也是希望大家能够自己debug进去看看这到底是如何递归的
*/
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
/**
* 省略代码
*/
// Process any @ComponentScan annotations
// 这个为什么是数组呢?当你使用@ComponentScans(value = {@ComponentScan("com.example.test"), @ComponentScan("com.example.test1")})
// 这里的长度就会变成3
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
// 开始以启动类扫描,这就是为什么启动类永远在所有包的最外层,如果要扫描其他模块或者启动类以外的包就要@ScanComponent这个注解
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 这里面就开始扫描doScan方法,只要是有@Component注解的都会把每个类的Definition放到scannedBeanDefinitions里面
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 这里有事解析这个Bean,跟刚刚的parser.parse一样,只是一个是数组一个是单个Bean
// 并且他会递归调用doProcessConfigurationClass()方法,并且重新执行一次获取看看这个类有没有@ComponentScan,并且继续扫描直至结束
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 其实每一个parse方法都会走到这里,把每个类的注解都会去循环一次,直至没有注解位置,会把@Import注解的类全部加载出来,这就是自动装配的原理
// 这就是为什么我其他jar包的类可以给Spring管理@Import就是一个重点,把这个类导入到BeanFactory里面
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
/**
* 省略代码
*/
return null;
}
创建Bean实例
/**
* 创建bean实例,这里的方法过于复杂用文章非常难解释,笔者这里就把大致的思路说下
* 1.getBean的时候先去createBean如果有就返回没有的话doCreateBean
* 2.当doCreateBean的时候就会触发bean的生命周期的各个接口
* 3.其实笔者发现一个东西,ApplicationContextAware并不算是bean生命周期的一环把,而是输入上下文的一环
* 4.因为ApplicationContextAware其实是由添加了AnnotationConfigServletWebServerApplicationContext类所导致的
* 5.创建bean的我会有下面的uml图让大家更能理解Bean是如何创建的
*/
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 获取所有的BeanName
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
关于ApplicationContext
实现ApplicationContextAware接口会调用setApplicationContext方法,而ApplicationContextAwareProcessor又是实现BeanPostProcessor,而ApplicationContextAwareProcessor又被Spring强制注册,所以说如果一个Bean实现ApplicationContextAware和BeanPostProcessor,在先初始化有关于BeanPostProcessor的Bean时候会创建这个Bean创建这个Bean的时候又会调用setApplicationContext方法调用完之后最后才会调用BeanPostProcessor实现的方法,其实听拗口的,所以最后还是希望自己能Debug一下
bean生命周期流程图
小结
当我重新重构这篇文章的时候,其实是因为我自己都读不懂之前的文章,希望这章大家可以看得懂。大家读不懂肯定是说明我的文采还不够好,也希望大家多多指出笔者的错误。
说到Spring其实在座的各位都是Spring工程师,老搬砖奴,但是大家肯定也因为忙没时间去研究整个Spring的流程。这里笔者帮大家都全部准备好了。
最后
最近我整理了整套《JAVA核心知识点总结》,说实话 ,作为一名Java程序员,不论你需不需要面试都应该好好看下这份资料。拿到手总是不亏的~我的不少粉丝也因此拿到腾讯字节快手等公司的Offer
进【Java进阶之路群】,找管理员获取哦-!
以上是关于读完这章,你还敢说你不会SpringBoot源码?的主要内容,如果未能解决你的问题,请参考以下文章