参照网址:
https://blog.csdn.net/u012855229/article/details/134515191
6 种方式读取 Springboot 的配置,老鸟都这么玩(原理+实战)-腾讯云开发者社区-腾讯云 (tencent.com)
一文读懂 Spring Environment - 掘金 (juejin.cn)
华为二面:SpringBoot读取配置文件的原理是什么?加载顺序是什么? (qq.com)
SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法 - 超级小小黑 - 博客园 (cnblogs.com)
spring boot容器启动详解_springboot 容器 启动-CSDN博客
BeanFactory的总结 - 张占岭 - 博客园 (cnblogs.com)
Spring 如何处理循环依赖?_spring list循环-CSDN博客
为什么使用双亲委派机制后,我们自定义的Bean仍能重写?具体看Spring 源码解析——@Configuration 作用及其实现原理(一)_@configuration 工作原理-CSDN博客
线程快照状态说明:Jstack查询线程堆栈_jstack 堆栈 分析-CSDN博客
循环依赖:烂大街的 Spring 循环依赖问题,你真以为自己会了吗? - 知乎 (zhihu.com)
笔记:
ConfigurableApplicationContext中 new SpringApplication(primarySources).run(args);
/**
*创建一个新的SpringApplication实例。应用程序上下文将从指定的主源加载bean(有关详细信息,请参阅类级文档)。实例可以在调用run(String…)之前自定义。
*resourceLoader:要使用的资源加载器
*primarysource:主要的bean源
*/
@SuppressWarnings({ "unchecked", "rawtypes" }) public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
// 初始化资源加载器,默认传递null this.resourceLoader = resourceLoader;
// 断言,如果主要加载资源为空,则报错 Assert.notNull(primarySources, "PrimarySources must not be null");
// 将加载资源转换为List,并放到LinkedHashSet中(LinkedHashSet具有去重效果)。 this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
// 获取当前web应用类型。内部判断的方式为:通过反射判断引用了那些包/类名。应用类型共有三种:1、该应用程序不应作为web应用程序运行,也不应启动嵌入式web服务器;2、应用程序应该作为一个基于servlet的web应用程序运行,并且应该启动一个嵌入式servlet web服务器;3、应用程序应该作为响应式web应用程序运行,并且应该启动一个嵌入式响应式web服务器。 this.webApplicationType = WebApplicationType.deduceFromClasspath();
// 将配置中心的相关信息注册到spring容器中(未初始化,将在run中的createBootstrapContext()进行初始化)。相关信息举例:如pom.xml引用的jar包中的spring.factories
this.bootstrapRegistryInitializers = new ArrayList<>(getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
// 初始化应用程序上下文。设置应用上线文初始化器,从"META-INF/spring.factories"读取ApplicationContextInitializer类的实例名称集合并去重,并进行set去重。(一共4个) setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
// 初始化监听器。设置监听器,从"META-INF/spring.factories"读取ApplicationListener类的实例名称集合并去重,并进行set去重。(一共10个) setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
// 推断主入口应用类,通过当前调用栈,获取Main方法所在类,并赋值给mainApplicationClass。 this.mainApplicationClass = deduceMainApplicationClass(); }
ConfigurableApplicationContext中 new SpringApplication(primarySources).run(args)
/**
*运行Spring应用程序,创建并刷新一个新的ApplicationContext。
*args:应用程序参数(通常从Java主方法传递)
*返回:运行的ApplicationContext
*/
public ConfigurableApplicationContext run(String... args) { long startTime = System.nanoTime();
// 将this.bootstrapRegistryInitializers的数据(即将)初始化到应用程序上下文中。目前只是初始化到“DefaultBootstrapContext bootstrapContext” DefaultBootstrapContext bootstrapContext = createBootstrapContext();
// 配置(初始化)应用程序上下文 ConfigurableApplicationContext context = null;
// 设置系统属性 `java.awt.headless` 的值,默认值为:true,用于运行headless服务器,进行简单的图像处理 configureHeadlessProperty();
// 创建所有 Spring 运行监听器并发布应用启动事件 SpringApplicationRunListeners listeners = getRunListeners(args);
// 启动监听 listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
// 初始化默认应用参数类 ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 根据运行监听器和应用参数来准备 Spring 环境 ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
// 配置忽略的BeanInfo configureIgnoreBeanInfo(environment);
// 打印横幅 Banner printedBanner = printBanner(environment);
// 创建应用程序上下文 context = createApplicationContext();
// 在应用程序上下文中设置ApplicationStartup,原文翻译为:为这个应用程序上下文设置ApplicationStartup。这允许应用程序上下文在启动期间记录指标。
context.setApplicationStartup(this.applicationStartup);
// 准备上下文处理
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
// 刷新上下文 refreshContext(context);
// 刷新上下文后处理。注:经查看源码,发现为空 afterRefresh(context, applicationArguments);
// 日志处理 Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime); if (this.logStartupInfo) { new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup); }
// 开始监听处理 listeners.started(context, timeTakenToStartup);
// 添加并运行所有Runners(ApplicationRunner/CommandLineRunner)运行器
callRunners(context, applicationArguments);
} catch (Throwable ex) {
// 异常处理
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
// 监听处理
listeners.ready(context, timeTakenToReady);
} catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
/**
创建环境前期准备:查找并设置配置文件信息
**/
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners, DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) { // 获取已经创建的环境或者根据获取当前web应用类型( this.webApplicationType = WebApplicationType.deduceFromClasspath())创建环境 ConfigurableEnvironment environment = getOrCreateEnvironment();
// applicationArguments.getSourceArgs():返回传递给应用程序的未处理的原始参数。
// 处理启动参数/源配置。模板方法按顺序委托给configurePropertySources(ConfigurableEnvironment, String[])和configureProfiles(ConfigurableEnvironment, String[])。覆盖此方法以实现对环境自定义的完全控制,或者覆盖上述方法之一,分别实现对属性源(configurePropertySources)或概要文件的细粒度控制(configureProfiles)。
// 注:1、configureEnvironment中的configurePropertySources方法里面的 是用来存放一些配置信息("并不提供直接操作该 MutablePropertySources 的方法,我们只能通过getPropertySources()方法获取 MutablePropertySources 实例,然后借助 MutablePropertySources 中的addFirst()、addLast()和replace()等方法去更新 PropertySource。")。原文解释:在此应用程序的环境中添加、删除或重新排序任何propertresources。
2、configureEnvironment中的configureProfiles经查看是空的,原定义为“为这个应用程序环境配置哪些概要文件是活动的(或默认情况下是活动的)。在配置文件处理过程中,可以通过spring.profiles.active属性激活其他配置文件。”
configureEnvironment(environment, applicationArguments.getSourceArgs());
// 两个作用:1、将ConfigurationPropertySource支持附加到指定的环境。2、调整优先级(.addFirst());
// 原文释义:将ConfigurationPropertySource支持附加到指定的环境。将环境管理的每个PropertySource适配为一个ConfigurationPropertySource,并允许经典的PropertySourcesPropertyResolver调用使用配置属性名进行解析。附加的解析器将动态跟踪来自底层环境属性源的任何添加或删除。
ConfigurationPropertySources.attach(environment);
// 处理监听相关事情。
listeners.environmentPrepared(bootstrapContext, environment);
// 移动'defaultProperties'属性源,使其成为给定ConfigurableEnvironment中的最后一个源。
DefaultPropertiesPropertySource.moveToEnd(environment);
Assert.state(!environment.containsProperty("spring.main.environment-prefix"), "Environment prefix cannot be set via properties.");
// 将创建的环境捆绑到SpringApplication上
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
// 判断是否存在自定义类型,如果不存在,则转换getClassLoader()给定的对象
EnvironmentConverter environmentConverter = new EnvironmentConverter(getClassLoader());
// 将给定环境转换为给定的StandardEnvironment类型。如果环境已经是相同的类型,则不执行转换,并且返回不变的环境。
environment = environmentConverter.convertEnvironmentIfNecessary(environment, deduceEnvironmentClass());
}
// 再次处理,确保优先级
ConfigurationPropertySources.attach(environment);
return environment;
}
笔记参照:SpringBoot启动流程分析(三):SpringApplication的run方法之prepareContext()方法 - 超级小小黑 - 博客园 (cnblogs.com)
/**
准备上下文处理
*/
private void prepareContext(DefaultBootstrapContext bootstrapContext, ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
// 配置应用程序上下文环境 context.setEnvironment(environment);
// 执行后置处理 postProcessApplicationContext(context);
// 执行容器中的 ApplicationContextInitializer 包括spring.factories和通过三种方式自定义的 applyInitializers(context);
// 向各个监听器发送容器已经准备好的事件 listeners.contextPrepared(context);
// 方法在BootstrapContext关闭和ApplicationContext准备好时被调用。 bootstrapContext.close(context);
// 判断是否开启日志信息打印 if (this.logStartupInfo) {
// 被调用来记录启动信息,子类可以重写以添加额外的日志记录。 logStartupInfo(context.getParent() == null);
// 调用以记录活动配置文件信息。 logStartupProfileInfo(context); } // 添加特定引导的单例bean。返回此应用程序上下文的内部bean工厂。可用于访问底层工厂的特定功能。注意:不要用它来后处理bean工厂;单例模式之前已经被实例化了。在接触bean之前,使用BeanFactoryPostProcessor来拦截BeanFactory设置过程。通常,这个内部工厂只有在上下文处于活动状态时才能访问,也就是说,在refresh()和close()之间。isActive()标志可用于检查上下文是否处于适当的状态。
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 将main函数中的args参数封装成单例Bean,注册进容器
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
// 如果printedBanner不为空,将其也注入容器
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
// 设置循环依赖,循环依赖相关可查这篇博客(Spring 如何处理循环依赖?_spring list循环-CSDN博客)学习
if (beanFactory instanceof AbstractAutowireCapableBeanFactory) {
((AbstractAutowireCapableBeanFactory) beanFactory).(this.allowCircularReferences);
if (beanFactory instanceof DefaultListableBeanFactory) {
((DefaultListableBeanFactory) beanFactory).setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
}
// 添加后置处理器。 if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// 添加后置处理器。属性源重新排序到任何由ConfigurationClassPostProcessor添加的@PropertySource项下面。
context.addBeanFactoryPostProcessor(new PropertySourceOrderingBeanFactoryPostProcessor(context));
// 当调用run(String…)时,返回将被添加到ApplicationContext中的所有源的不可变集合。此方法将构造函数中指定的任何主要源与已显式设置的任何其他源组合在一起。
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 加载我们的启动类,将启动类注入容器
load(context, sources.toArray(new Object[0]));
// 监听处理。发布容器已加载事件
listeners.contextLoaded(context);
}
CommandLineRunner和ApplicationRunner_applicationrunner 和commandlinerunner-CSDN博客
Spring扩展点(一):后置处理器PostProcessor_springboot后置处理器-CSDN博客
关于Bean处理:getBean(String name)->doGetBean(...)->getSingleton(beanName)->getSingleton(String beanName, ObjectFactory<?> singletonFactory) -> createBean -> doCreateBean -> createBeanInstance -> addSingletonFactory -> populateBean -> initializeBean -> addSingleton -> getObjectForBeanInstance
一、getBean(String name):获取一个Bean对象/实例 AbstractBeanFactory.java
二、doGetBean(...):获取一个Bean对象/实例
AbstractBeanFactory.java
1、获取bean对象(三级缓存/循环依赖) Object sharedInstance = getSingleton(beanName);
一级缓存(singletonObjects):存放已经完全实例化、属性填充、初始化等操作的bean;
二级缓存(earlySingletonObjects):存放原始的Bean(半成品/仅完成实例化,初始化属性赋值等未完成),区别于三级缓存:该级缓存下的Bean已经提前暴露并能够引用(已在后置处理器中生效);
三级缓存(singletonFactories):存放早期的Bean,仅完成实例化,能够提前暴露但是在后置处理器无法使用。 /**
* 返回以给定名称注册的(原始)单例对象。 * <p>检查已经实例化的单例,也允许早期的 *引用当前创建的单例(解析循环引用)。 * @param beanName要查找的bean的名称 * @param allowEarlyReference是否应该创建早期引用 * @返回注册的单例对象,如果没有找到则返回{@code null} */ @Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从一级缓存中获取Bean对象 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 从二级缓存中获取Bean对象 singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) {
// 从三级缓存中获取Bean对象,如果能够找到将其从三级缓存中移除,并添加到二级缓存中去
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
2、返回在给定名称下注册的(原始)单例对象,如果还没有注册,则创建并注册一个新对象。
getSingleton(String beanName, ObjectFactory<?> singletonFactory) -> createBean -> doCreateBean -> createBeanInstance -> addSingletonFactory -> populateBean -> initializeBean -> addSingleton -> getObjectForBeanInstance
sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { //显式地从单例缓存中删除实例:它可能已经放在那里了 //创建过程中,允许循环引用解析。 //同时删除所有接收到临时引用的bean。 destroySingleton(beanName); throw ex; } });
3、getSingleton(String beanName, ObjectFactory<?> singletonFactory)
/** * 返回在给定名称下注册的(原始)单例对象,如果还没有注册,则创建并注册一个新对象。 */ public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null");
// 对一级缓存进行加锁
synchronized (this.singletonObjects) {
// 加锁后再一次尝试获取Bean对象,如果存在,直接返回
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 (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); }
// 判断是否正在创建(排除创建状态)或者添加到创建状态,如果不在排除状态和已经在创建状态,那么会抛出"BeanCurrentlyInCreationException(beanName)"异常
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try {
// 获取CreateBean(...)创建的实例 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) {
//在此期间是否隐式出现了单例对象->如果是,则继续执行,因为异常指示该状态。
singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; }
// 默认实现将单例标记为不再处于创建状态。 afterSingletonCreation(beanName); } if (newSingleton) {
// 将给定的单例对象添加到该工厂的单例缓存中。 addSingleton(beanName, singletonObject); } } return singletonObject; } }
4、createBean
/** * 创建一个bean实例 */ @Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd;
//确保bean类在此时被解析,在动态解析类的情况下克隆bean定义,不能存储在共享合并bean定义中。
// 为mdb解析出对应的bean class。详细内容可查看:Spring 5 AbstractBeanFactory -- resolveBeanClass源码解析_typestomatch-CSDN博客
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
// 重新创建BeanClass mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. try {
// 验证并准备为此bean定义的方法覆盖 mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 应用实例化前的后处理器(前置处理器),解析指定bean是否存在实例化前的快捷方式。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } try {
// 实际创建指定的bean。 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
5、doCreateBean
参照博文:Spring源码解析之-doCreateBean() 详解_docreatebean 源码详解-CSDN博客
/** * 实际创建指定的bean。创建前处理已经完成 * 此时,例如检查{@code postProcessBeforeInstantiation}回调。 * 区分默认bean实例化、使用工厂方法和自动构造函数。 * @param beanName bean的名称 * @param MBD为bean合并的bean定义 * @param args用于构造函数或工厂方法调用的显式参数 * @返回bean的新实例 * 如果bean不能被创建,@ BeanCreationException * @参见#instantiateBean * @参见#instantiateUsingFactoryMethod * @参见#autowireConstructor
*/
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) {
// 判断是否是单例模式,如果是,从FactoryBean(未完成的FactoryBean实例的缓存:FactoryBean名称到BeanWrapper。)缓存中获取并清除 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) {
// 非单例或者获取不到,创建Bean实例 instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) {
// 设置解析类型 mbd.resolvedTargetType = beanType; } // 允许后处理器修改合并的bean定义。(后置处理器处理) synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } }
//主动缓存单例以解析循环引用
//即使被BeanFactoryAware等生命周期接口触发。
// 是否需要提前曝光: 单例& 允许循环依赖 & 当前bean正在创建中, 检查循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); }
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} // 初始化bean实例。 Object exposedObject = bean; try {
// 对Bean进行字段、属性填充、注入。 // 对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,会递归初始化 populateBean(beanName, mbd, instanceWrapper);
// 初始化bean。如:Awire的设置,前置和后置处理。 exposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) { if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) { throw (BeanCreationException) ex; } else { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex); } } // 循环依赖处理 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; // 获取到二级缓存的引用直接返回引用 } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// 判断是否存在DependentBeanMap,存在就获取并检查依赖 String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!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 " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 注册到disposableBean中,以便销毁bean的时候可以执行相关处理. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
6、createBeanInstance
/**
*使用适当的实例化策略:工厂方法、自动构造函数或简单实例化,为指定的bean创建一个新实例。
形参:beanName—bean的名称mbd—bean参数的bean定义—用于构造函数或工厂方法调用的显式参数
返回值:新实例的BeanWrapper
请参阅:obtainFromSupplier, instantiateUsingFactoryMethod, autowireConstructor, instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 确保bean类在此时实际上已被解析。 Class<?> beanClass = resolveBeanClass(mbd, beanName); // 判断BeanClass是否是Public类型 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()); } // 获取创建Bean的实例回调 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) {
// 如果存在,返回。obtainFromSupplier进行了当前(beanName的)Bean的设置和清空,和创建(返回的是创建和初始化后的BeanWrapper)
return obtainFromSupplier(instanceSupplier, beanName);
}
// 判断是否存在工厂方法名称
if (mbd.getFactoryMethodName() != null) {
//使用命名工厂方法实例化bean。如果mbd参数指定了一个类,而不是一个factoryBean,或者是使用依赖注入配置的工厂对象本身的实例变量,那么该方法可能是静态的。
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 重新创建相同bean时的快捷方式…
// 通过参数和类型确定构造器
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 存在已解析的构造器
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 使用已解析的构造器构造
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 使用默认构造器构造
return instantiateBean(beanName, mbd);
}
}
// 构造函数处理
// Candidate constructors for autowiring? Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? ctors = mbd.getPreferredConstructors(); if (ctors != null) { return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. return instantiateBean(beanName, mbd); }
7、addSingletonFactory
/**
添加三级缓存
*添加给定的单例工厂,以便在必要时构建指定的单例。
*为单例的即时注册调用,例如能够解析循环引用。
* @param beanName bean的名称
* @param singletonFactory是单例对象的工厂
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } } }
8、populateBean
/** *使用来自bean定义的属性值在给定的BeanWrapper中填充bean实例。
* @param beanName bean的名称
* @param MBD bean的定义
* @param在bean实例的BeanWrapper
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) {
// 不能将属性属性的值放到空实例里面去 throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // 跳过空实例的属性填充阶段。 return; } }
//给任何InstantiationAwareBeanPostProcessors修改实例的机会
//设置属性前的状态。例如,这可以用于支持字段注入的样式。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
// 获取mbd中的属性值
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
// 获取解析后的自动装配模式
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// 如果适用,根据名称自动添加属性值。
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// 如果适用,根据类型自动添加属性值。
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
// 返回该工厂是否持有一个实例化的awarebeanpostprocessor,该实例化将在创建时应用于单例bean。
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
// 判断mbd的依赖检查是否是None,如果不是为true
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) {
// 从给定的BeanWrapper中提取一组过滤过的PropertyDescriptors,排除忽略的依赖类型或在忽略的依赖接口上定义的属性。 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); }
// 依赖注入属性 pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); }
// 进行依赖检查 checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) {
// 将属性字段等从临时的Pvs中注入到Bean中 applyPropertyValues(beanName, mbd, bw, pvs); } }
9、initializeBean
Spring源码(十二)-初始化Bean-initializeBean - 掘金 (juejin.cn)
/**
*初始化给定的bean实例,应用工厂回调以及初始化方法和bean后处理程序。
* <p>从{@link #createBean}调用传统定义的bean,从{@link #initializeBean}调用现有的bean实例。
* @param beanName在工厂中的bean名称(用于调试目的)
@param bean:我们可能需要初始化的新bean实例
* @param MBD创建bean时使用的bean定义(如果给定一个现有的bean实例,也可以是{@code null})
* @返回初始化的bean实例(可能被包装)
* @参见BeanNameAware
* @参见BeanClassLoaderAware
* @参见BeanFactoryAware
* @参见#applyBeanPostProcessorsBeforeInitialization
* @参见#invokeInitMethods
* @参见#applyBeanPostProcessorsAfterInitialization
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) {
// 判断是否建立了系统安全管理器。如果已经为当前应用程序建立了安全管理器,则返回该安全管理器;否则,返回null。 AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
// 激活自动装配(Aware)方法
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 激活自动装配(Aware)方法
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) {
// 前置处理器处理 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try {
// 初始化处理 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) {
// 后置处理器处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
/**
*现在给bean一个机会做出反应,它的所有属性都设置好了,并且有机会知道它拥有的bean工厂(这个对象)。
*这意味着检查bean是否实现了InitializingBean或定义了自定义初始化方法,如果实现了,则调用必要的回调。
* @param beanName在工厂中的bean名称(用于调试目的)
@param bean:我们可能需要初始化的新bean实例
* @param MBD创建bean时使用的合并bean定义(如果给定一个现有的bean实例,也可以是{@code null})
* @throws Throwable如果被init方法或调用进程抛出
* @参见#invokeCustomInitMethod
*/
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
// 判断是否实现了实现了InitializingBean
boolean isInitializingBean = (bean instanceof InitializingBean);
// hasAnyExternallyManagedInitMethod:确定给定的方法名称是否指示外部管理的初始化方法,而不考虑方法的可见性。
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
/**在设置了所有bean属性并满足BeanFactoryAware、ApplicationContextAware等要求后,由包含bean的BeanFactory调用。
此方法允许bean实例在设置了所有bean属性后对其总体配置和最终初始化执行验证。
抛出: 异常-在配置错误的情况下(例如设置基本属性失败),或者由于任何其他原因导致初始化失败
*/
((InitializingBean) bean).afterPropertiesSet(); return null; }, getAccessControlContext()); } catch (PrivilegedActionException pae) { throw pae.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.hasAnyExternallyManagedInitMethod(initMethodName)) {
// 反射调用init-method方法 invokeCustomInitMethod(beanName, bean, mbd); } } }
10、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对象是否是FactoryBean
getObjectForBeanInstance
bean的实例中获取对象_getobjectforbeaninstance-CSDN博客
【保姆级·创建对象】如何利用resolveBeforeInstantiation()在预处理阶段返回一个Bean的实例对象-CSDN博客
*引用当前创建的单例(解析循环引用)。
* @param beanName要查找的bean的名称
* @param allowEarlyReference是否应该创建早期引用
* @返回注册的单例对象,如果没有找到则返回{@code null}