本文章出处 Spring 使用 xml 启动源码解析
转载请说明出处
工程准备
- 引入 Spring 最小依赖
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.1.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
- applicationContext.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myBean" class="org.ting.spring.study.App"/>
</beans>
- Spring 启动代码
package org.ting.spring.study;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App
{public static void main( String[] args ){ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
App myBean = (App) app.getBean("myBean");
System.out.println(myBean);
}
}
了解 ClassPathXmlApplicationContext
这个类基本上都是构造函数
可以看出,这个没有任何业务逻辑代码,都是通过继承抽象类扩展功能,主要业务都在父类中。下面我们看下构造方法是怎么初始化 Spring 容器的
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[] {configLocation}, true, null);
}
进入 this 构造方法
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 设置父容器
super(parent);
setConfigLocations(configLocations);
if (refresh) {refresh();
}
}
可以看出,这个才是 ClassPathXmlApplicatonContext 实例化方法,设置父容器对象,添加配置文件路径到容器中,开始启动容器工作。super(parent)
方法依次调用服务父类 AbstractXmlApplicationContext
、AbstractRefreshableConfigApplicationContext
、AbstractRefreshableApplicationContext
、AbstractApplicationContext
的构造方法。
public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();
setParent(parent);
}
@Override
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
if (parent != null) {Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
这个方法主要是向上调用父类构造方法,一直到 AbstractApplicationContext 对象。参数不为空的话将父上下文对像 Environment
设置合并到当前容器中,将两个容器配置文件合并起来,一般在 web 环境有使用到。
setConfigLocations
public void setConfigLocations(@Nullable String... locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {// 处理路径,从环境变量中替换占位符 ${x}
this.configLocations[i] = resolvePath(locations[i]).trim();}
}
else {this.configLocations = null;}
}
将路径添加到AbstractRefreshableConfigApplicationContext
configLocations 属性中,并且出来掉路径中环境变量占位符,保证 configLocaiton 得到是可用地址。
refresh 解读
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
// 准备刷新上下文对象
prepareRefresh();
// 创建 Spring Factory 对象,清空缓存,解析 xml 文件转换成 BeanDefinition 保存到缓存中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 初始化 BeanFactory 内部属性值,添加类型转换 , 前置处理器
prepareBeanFactory(beanFactory);
try {
// 空方法,让字类实现查看或者修改 beanFacory 内部属性值
postProcessBeanFactory(beanFactory);
// 注册实例化 BeanFactoryPostProcessor,并且执行所有类接口方法
invokeBeanFactoryPostProcessors(beanFactory);
// 注册所有后置处理器
registerBeanPostProcessors(beanFactory);
// 初始化 messageSource bean
initMessageSource();
// 初始化组播器
initApplicationEventMulticaster();
// 空方法,让字类自行初始化特别 bean
onRefresh();
// 初始化所有事件监听器,加入组播器中,广播事件
registerListeners();
// 启动所有非延迟单例 bean
finishBeanFactoryInitialization(beanFactory);
// 完成 applicationContext 初始化工作
finishRefresh();}
catch (BeansException ex) {if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization -" +
"cancelling refresh attempt:" + ex);
}
// 销毁已经创建成功 bean
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// 清空所有类型注解扫描,反射等元数据集合
resetCommonCaches();}
}
}
下面我们一个个方法解析
prepareRefresh
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {if (logger.isTraceEnabled()) {logger.trace("Refreshing" + this);
}
else {logger.debug("Refreshing" + getDisplayName());
}
}
// 初始化 PropertySource,默认不做任何处理,让子类实现
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
if (this.earlyApplicationListeners == null) {this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
this.earlyApplicationEvents = new LinkedHashSet<>();}
设置启动时间,将关闭标记设置 false,活动开关设置 true,initPropertySources(), 本身是一个空方法,由子类自行去实现,让子类在容器创建之前修改 ConfigurableEnvironment
的PropertySources
对象属性。PropertySources
name/value 键值对的封装接口,主要用来装配配置变量。虽然 ClassPathXmlApplicatonContext
和他的父类都没有实现这个方法,在 Spring MVC 中,GenericWebApplicationContext
实现 initPropertySources 方法,将 servletContext
配置变量合并到 ProertySources
中。接着看 getEnvironment().validateRequiredProperties()这个方法实现在
validateRequiredProperties
@Override
public void validateRequiredProperties() {MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {if (this.getProperty(key) == null) {ex.addMissingRequiredProperty(key);
}
}
if (!ex.getMissingRequiredProperties().isEmpty()) {throw ex;}
}
主要校验 ProertySources
中 key value,是否有不对应的情况。其实这个主要校验上一个 initPropertySources()方法安全措施来的。比如老爸放手让自己儿子去做一件事,自己完全不干预,但是他会偷偷去查看事件做得怎么样?如果做不不行,狠狠打儿子一顿。
ConfigurableListableBeanFactory 初始化
这部分应该是整个代码解析最核心的功能了,这个类就是我们经常说的 Spring 容器,Spring 工厂的实现 DefaultListableBeanFactory
。主要负责 bean 注册实例化,bean 查找,bean 别名,bean 销毁。这里实例化这个对象,也开始说明 Spring 生命周期正式开始。下面是 DefaultListableBeanFactory 的继承关系
查看 obtainFreshBeanFactory 方法具体内容
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {refreshBeanFactory();
return getBeanFactory();}
refreshBeanFactory 主要是清除 ConfigurableListableBeanFactory bean 缓存,重新实例化。
refreshBeanFactory
这个方法在 AbstractRefreshableApplicationContext
中
protected final void refreshBeanFactory() throws BeansException {if (hasBeanFactory()) { // 判断 ConfigurableListableBeanFactory 是否已经创建了
destroyBeans();
closeBeanFactory();}
try {
// 使用构造函数实例化 new DefaultListableBeanFactory(parent)DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//Spring 工厂自定义设置,是否运行已经注册 bean 被相同 beanName 覆盖,默认是 true,设置是否允许 bean 之间的循环引用 - 并尝试自动解决它默认也是 true
customizeBeanFactory(beanFactory);
// 开始解析 xml 配置文件,注册 BeanDefinition, 下面具体分析
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {this.beanFactory = beanFactory;}
}
catch (IOException ex) {throw new ApplicationContextException("I/O error parsing bean definition source for" + getDisplayName(), ex);
}
}
先判断 ConfigurableListableBeanFactory 对象是否已经创建成功了,如果已经存在了,执行销毁 Spring 容器内已经注册 bean 销毁,重新实例化 ConfigurableListableBeanFactory 对象,设置 id,设置 beanFactory bean 重名,依赖解决方式。开始加载 xml 配置文件,注册 BeanDefinition,将已经实例化 BeanFactory 指引再指向 this.beanFactory。
主要看下 destroyBeans()
protected void destroyBeans() {getBeanFactory().destroySingletons();}
调用了 ConfigurableListableBeanFactory 的 destroySingletons 方法,接口的实现类是DefaultListableBeanFactory
。
@Override
public void destroySingletons() {super.destroySingletons();
updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
clearByTypeCache();}
destroySingletons
super.destroySingletons()调用了 DefaultSingletonBeanRegistry
的destroySingletons
方法
public void destroySingletons() {if (logger.isTraceEnabled()) {logger.trace("Destroying singletons in" + this);
}
synchronized (this.singletonObjects) {this.singletonsCurrentlyInDestruction = true;}
String[] disposableBeanNames;
synchronized (this.disposableBeans) { // 将 map key 转化成 string 数组
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {destroySingleton(disposableBeanNames[i]);
}
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear();
clearSingletonCache();}
destroySingleton
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName);
// Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
}
查看 removeSingleton 方法
protected void removeSingleton(String beanName) {synchronized (this.singletonObjects) {this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
}
这几个分别就是内部容器来的,看下主要用途
/** 缓存单例 bean 对象:beanName 对应 bean 对象 */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** 缓存单例工厂: beanName 对应 bean 工厂实体. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** 缓存 bean 早期对象,主要是 bean 注册的实体依赖对象: beanName 对应 实体对象 */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
/** 已经成功注册 beanName, 按住注册顺序保存 */
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
destroyBean
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Trigger destruction of dependent beans first...
Set<String> dependencies;
synchronized (this.dependentBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
dependencies = this.dependentBeanMap.remove(beanName);
}
if (dependencies != null) {if (logger.isTraceEnabled()) {logger.trace("Retrieved dependent beans for bean'" + beanName + "':" + dependencies);
}
for (String dependentBeanName : dependencies) {destroySingleton(dependentBeanName);
}
}
// Actually destroy the bean now...
if (bean != null) {
try {bean.destroy();
}
catch (Throwable ex) {if (logger.isInfoEnabled()) {logger.info("Destroy method on bean with name'" + beanName + "'threw an exception", ex);
}
}
}
// Trigger destruction of contained beans...
Set<String> containedBeans;
synchronized (this.containedBeanMap) {
// Within full synchronization in order to guarantee a disconnected Set
containedBeans = this.containedBeanMap.remove(beanName);
}
if (containedBeans != null) {for (String containedBeanName : containedBeans) {destroySingleton(containedBeanName);
}
}
在删除 DisposableBean 实例的时候,获取 bean 下依赖实例,逐个移除。最后将 Spring 容器依赖实体逐个移除。接着看 closeBeanFactory()
办法
loadBeanDefinitions 解析
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
//xml 文件约束校验
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// 设置 xml 校验方式
initBeanDefinitionReader(beanDefinitionReader);
// 开始解析 xml 转化 BeanDefinition
loadBeanDefinitions(beanDefinitionReader);
}
实例化 XmlBeanDefinitionReader
将资源文件 xml 解析成 BeanDefinition,将 Spring 上下文对象赋值给对象属性。loadBeanDefinitions 会将 xml 文件转化成 Document
对象,由于这部分太过繁琐,需要根据文件名获取 ResouceLoader,再获取到文件流对象,解析 xml 成 Document,觉得省略这些代码解析,主要放在 Document 如何转化成 BeanDefinition
,在DefaultBeanDefinitionDocumentReader
实现。
doRegisterBeanDefinitions
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
// 判断文件 profile 属性,转化成 array
if (StringUtils.hasText(profileSpec)) {String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching:" + getReaderContext().getResource());
}
return;
}
}
}
// 运行自定义实现类 预处理 xml 文件,空方法,让子类实现。preProcessXml(root);
parseBeanDefinitions(root, this.delegate);
// 运行自定义自主实心方法,修改 xml 属性,空方法。postProcessXml(root);
this.delegate = parent;
}
BeanDefinitionParserDelegate
主要是解析 Document 命名空间,标签元素,属性,将 xml 标签转化成对象。
prseBeanDefinitions
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {if (delegate.isDefaultNamespace(root)) {NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {Node node = nl.item(i);
if (node instanceof Element) {Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// 注册 BeanDefinition
parseDefaultElement(ele, delegate);
}
else {delegate.parseCustomElement(ele);
}
}
}
}
else {delegate.parseCustomElement(root);
}
}
循环遍历 beans
的子标签,符合 ”import”, “alias”, “bean” 命名空间,进入标签解析环节
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
主要看下 bean 标签解析
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {getReaderContext().error("Failed to register bean definition with name'" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
这个方法将 xml 解析返回 BeanDefinition 对象,如果对象不为空,继续解析元素的自定义属性,并将元素自定义属性设置给刚刚创建 BeanDefiniton 对象,最后广播注册 BeanDefinition 对象。关于如何生成 BeanDefiniton 对象,这个方法我不具体深入了解了,毕竟里面篇幅很多的,以后会专门出一个章节去说明。
prepareBeanFactory 方法解析
prepareBeanFactory 方法主要是配置 BeanFactory 类加载器,Spring el 表达式实现,bean 前置处理器等等的属性设置,主要逻辑详看下面的代码
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 设置工厂类加载器 beanFactory.setBeanClassLoader(getClassLoader());
// 设置 Spring el 表达式实现
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加属性转化器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
/*
* 添加后置处理器实现, 如果实现了相应的 Aware 接口,则注入对应的资源
* 1. EnvironmentAware
* 2. EmbeddedValueResolverAware
* 3. ResourceLoaderAware
* 4. ApplicationEventPublisherAware
* 5. MessageSourceAware
* 6. ApplicationContextAware
*/
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);
// 将 Spring 内部对象缓存起来,注册到容器内部。beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 注册 事件监听器前置处理
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 判断存在 AOP bean name 则注册 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()));
}
// 注册 默认 environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
// 向 Spring 容器注册 bean
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());0
}
}
BeanPostProcessor
addBeanPostProcessor 方法主要添加 BeanPostProcessor 接口实现类,Bean 的后置处理器,主要是在 bean 初始化前后进行一些处理工作,spring bean 创建委派给个大后置处理器创建。
public interface BeanPostProcessor {
/**
* bean 在创建之前,对 bean 进行处理,将处理过实体返回给 BeanFactory 容器
*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}
/**
* bean 创建之后,对 bean 进行处理,相当于给已经创建的进行功能加强
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}
}
ApplicationContextAwareProcessor
@Override
@Nullable
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {acc = this.applicationContext.getBeanFactory().getAccessControlContext();}
if (acc != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {if (bean instanceof Aware) {if (bean instanceof EnvironmentAware) {((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
上面的逻辑非常判断准备初始化 bean 是否实现了 EnvironmentAware
,EmbeddedValueResolverAware
,ResourceLoaderAware
,ApplicationEventPublisherAware
,MessageSourceAware
.ApplicationContextAware
接口,如果是,直接执行接口方法,将 Spring 工厂方法注入属性中。这个也解析了上面设置 registerResolvableDependency
依赖注入忽略。
postProcessBeanFactory
postProcessBeanFactory 方法中没有任何实现,主要是允许子类在 Spring 工厂还没有初始化 bean 之前,添加一些特殊 bean 进入到容器中,比如添加 BeanPostProcessors 接口实现类。这时候 Spring 已经解析完 xml,还需要想添加一些 bean 到容器中,这时候就可以实现这个方法。
invokeBeanFactoryPostProcessors
BeanFactoryPostProcessors 接口跟 BeanPostProcessor 类似,可以用于 bean 的定义进行处理,也可以在 bean 初始化之前修改 bean 元数据。可以配置多个 BeanFactoryPostProcessor,使用 Order 接口来控制执行顺序。源码展示
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行 BeanFactoryPostProcessors,从容器中已经实例化对象中执行方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {// 判断是否需要 AOP 支持,注册 AOP 前置处理器
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
invokeBeanFactoryPostProcessors
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) { // 强制类型 BeanDefinitionRegistryPostProcessor 接口需要用到
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 遍历所有 BeanFactoryPostProcessor,按照 BeanFactoryPostProcessor 类型和 BeanDefinitionRegistryPostProcessor 类型分别放入不用容器中,// 并且执行 BeanDefinitionRegistryPostProcessor 接口方法。for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry); // 执行接口方法,参考或者修改 bean 元数据
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.
// 获取工厂中所以 BeanDefinitionRegistryPostProcessor 类型 bean
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);
// 执行集合中所有 BeanDefinitionRegistryPostProcessors 接口方法
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);
}
}
// 根据 order 接口排序集合中的顺序
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<>();
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<>();
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();}
看起来代码挺多,其实很简单的逻辑。
- 遍历循环所有
BeanFactoryPostProcessor
集合,首先取出BeanDefinitionRegistryPostProcessor
,并且执行接口方法,再放入 registryProcessors 容器中。 - BeanFactory 中获取所有
BeanDefinitionRegistryPostProcessor
类型的 bean name 数组,遍历循环数据,判断是否有PriorityOrdered
接口,加入容器中,并且根据接口重新排序后,遍历容器所有类,执行接口方法,加入 registryProcessors 容器中。 - 在获取容器所有
BeanDefinitionRegistryPostProcessor
类型的 bean name 数组,循环遍历 bean name 取出实现Ordered
接口, 按照Orderd
顺序排序集合,依次执行接口方法,加入放入 registryProcessors 容器中. - 将剩下所有 BeanDefinitionRegistryPostProcessor,加入 registryProcessors 容器中。执行 registryProcessors 容器中所有
BeanFactoryPostProcessor
的接口方法。 -
BeanFactoryPostProcessor
也是按照上面的思路,先过滤排序执行接口方法。
看到这里我有一个疑问,这些接口对象怎么产生的?Spring 工厂并没有开始实例化对象,这时候 Spring 只进行到将 xml 转化成 beanDefinition 这个对象, 不可能从 Spring 工厂获取出来的。
BeanFactoryPostProcessor 实例化过程
实例化 bean 的方法主要在 AbstractBeanFactory
中
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 取出 & 提取对应 beanName
final String beanName = transformedBeanName(name);
Object bean;
// 在缓存中获取对象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean'" + beanName +
"'that is not fully initialized yet - a consequence of a circular reference");
}
else {logger.trace("Returning cached instance of singleton bean'" + beanName + "'");
}
}
// 判断缓存中对象是否是正确的 bean 实例化,如果是 FactoryBean 接口对象,调用接口方法获取到 bean 实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果 beanName 是 prototpe 或者 scope 类型,并且正在创建中,直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
// 尝试在父容器获取
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 没有找到,尝试修改 beanName 名称,重新来过
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {return (T) parentBeanFactory.getBean(nameToLookup);
}
}
// 如果只是做类型检查,不进行实例化,这将 bean 加入创建记录中
if (!typeCheckOnly) {markBeanAsCreated(beanName);
}
try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 判断 BeanDefinition 类型不是抽象类
checkMergedBeanDefinition(mbd, beanName, args);
// 获取 bean 元数据所有依赖 bean
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) { // 检查是否存在依赖关系
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between'" + beanName + "'and'" + dep + "'");
}
// 相互添加依赖和被依赖的关联
registerDependentBean(dep, beanName);
try {getBean(dep); // 实例化创建依赖 bean
}
catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'"+ beanName +"' depends on missing bean '"+ dep +"'", ex);
}
}
}
// 创建单例对象
if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {
try {
// 具体创建 bean 方法,由子类 AbstractAutowireCapableBeanFactory 实现
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 添加创建记录
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
// 删除记录
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {String scopeName = mbd.getScope();
final 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, () -> {beforePrototypeCreation(beanName);
try {return createBean(beanName, mbd, args);
}
finally {afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
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",
ex);
}
}
}
catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// 类型检查 得到 bean 可能是 String 类型,但是需要转化成 Integer 类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
// 使用类型转化器
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean'" + name + "'to required type'" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
这个就是 Spring 创建 bean 具体流程,但是任然还有很多细节没有表达出来,看了这么多源码,都知道一个方法不可能放得下这么多逻辑的。以后有机会我入深入每个方法再具体讲解的。主要总结下 Spring 创建 bean 整体路程。
- 处理 beanName,去除 FactoryBean 的修饰符,也就是 ”&name” 转化成 ”name”。将 alias name 转化成真正 beanName。
- 如果是否是单例,尝试从缓存中加载 bean。再处理缓存中 bean,在缓存中记录的只是最原始 bean,并一定是我们最终想要的 bean,需要 getObjectForBeanInstance 來完成這個工作。
- 原型依赖检查
- 尝试从父容器中获取 bean,如果父容器不为空并且包含 beanName 情况下。
- 获取 beanName 下所有的依赖 bean,并且实例化所有的依赖 bean
- 根据对象 scope 分别实例化 bean。
- 实例化结束后,将对象转化成 requiredType 给定类型。
registerBeanPostProcessors
注册所有 BeanPostProcessor
后置处理类,这里只是注册,不会执行任何接口方法。具体流程跟上面 BeanFactoryPostProcessor
非常相似。在 PostProcessorRegistrationDelegate
看下具体代码逻辑,注意与上面代码相似地方。
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 根据类型获取所有 BeanPostProcessor beanName
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 注册 BeanPostProcessorChecker 只是一个 info 日志信息打印类
// 当一个 bean 正在被 BeanPostProcessor 创建时就会打印信息
// 这个 bean 不能是 BeanPostProcessor 类型
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 使用 PriorityOrdered 排序 bean 执行顺序
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//MergedBeanDefinitionPostProcessor 接口容器
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
// 使用 Ordered 接口排序 bean 执行顺序
List<String> orderedPostProcessorNames = new ArrayList<>();
// 默认顺序排序
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 匹配类型
BeanPostProcessor pp = 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);
}
}
// 首先注册 PriorityOrdered 优先排序
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 只是注册处理器,不调用方法
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 接着注册 Ordered 类型 优先排序
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 注册所有常规 BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最后注册 MergedBeanDefinitionPostProcessor 类型
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 注册 ApplicationListener 后置处理器
// 添加到所有处理器链后面
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
BeanPostProcessor
注册流程跟上面 BeanFactoryPostProcessor
非常相似啊。
- 根据
BeanPostProcessor
获取所有后置处理器 beanName - 根据 beanName 数组长度创建
BeanPostProcessorChecker
对象,并注册到容器中。 - 根据 PriorityOrdered,MergedBeanDefinitionPostProcessor,Ordered,等类型分别创建不同处理器容器
- 根据不同类型排序注册处理器
initMessageSource
初始化信息资源类,Spring 内部国际化支持。逻辑非常简单,先判断容器内是否有messageSource
, 直接注册 bean,否则 Spring 内部注册DelegatingMessageSource
。代码我就不放出来了,有兴趣同学自行去查看。
initApplicationEventMulticaster
初始化 ApplicationEventMulticaster
事件组播器,主要判断用户是否自定义了事件组播器,直接使用用户定义的组播器。如果没有用户自定义组播器,默认使用SimpleApplicationEventMulticaster
,代码略 …
onRefresh
初始化其他特殊 bean,由子类自行实现。这里又是使用了模板方法设计模式,让使用者可以扩展新功能。
registerListeners
注册所有实现 ApplicationListeners 接口的监听器,添加到上面刚刚初始化组播器中。获取所有事件集合,发布到组播器中,组播器再广播到监听指定事件的监听器中。
protected void registerListeners() {
// Register statically specified listeners first.
for (ApplicationListener<?> listener : getApplicationListeners()) {getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {for (ApplicationEvent earlyEvent : earlyEventsToProcess) {getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishBeanFactoryInitialization
这个方法就是我们解析 Spring IOC 核心了,初始化所有 Spring bean,看这么多代码,终于到了我们最想了解部分了,直接上代码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化 conversion service 用于类型转化
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 如果没有后置处理器,默认就支持嵌入值解析器
// 例如 PropertyPlaceholderConfigurer bean 之前注册的任何一个
// 主要用于配置占位符解析
if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 在所有 bean 初始化之前初始化所有 AOP 代理对象
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);
}
// 取消临时类加载器,关闭类型查找 beanFactory.setTempClassLoader(null);
// 冻结所有 beanDefinition 特性
beanFactory.freezeConfiguration();
// 初始化非延迟单例 bean (创建所有 bean)
beanFactory.preInstantiateSingletons();}
- 判断容器内是否有
conversionService
, 并且类型必须是 ConversionService,则实例化 bean。ConversionService 接口也是个类型转换器。 - 判断容器内是否有
StringValueResolver
类型 bean,没有手动注册一个。 - 初始化所有 AOP 通知类型。
4. 冻结所有 bean 元数据特性,不允许任何修改。
- 实例化所有非延迟单例 bean
preInstantiateSingletons
public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in" + this);
}
// 遍历所有 beanDefinitionNames,copy 到信息 list 中
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 实例化所有非延迟 bean
for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {// 判断 FactoryBean 接口类型 bean
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);
}
}
}
// 执行 bean 中实现 SmartInitializingSingleton 接口,执行接口方法,用与单例 bean 初始化成功后执行
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();
}
}
}
}
finishRefresh
protected void finishRefresh() {
// 清空容器中 Resource 缓存
clearResourceCaches();
// 初始化 LifecycleProcessor,注册到 Spring 容器中
initLifecycleProcessor();
// 调用上面刚刚注册 LifecycleProcessor onRefresh 方法
getLifecycleProcessor().onRefresh();
// 发布 ApplicationContext 完成初始化事件
publishEvent(new ContextRefreshedEvent(this));
// 如果配置文件中存在 spring.liveBeansView.mbeanDomain 初始化 LiveBeansView 注册到容器中
LiveBeansView.registerApplicationContext(this);
}
到这里说明 Spring 创建 bean 过程差不多完成了,但是还有很多细节没有展示出来,因为篇幅实在太多了。可以看出我前面讲得还是比较详细的,到了后面简略一些方法解析,篇幅实在太长了。如果有哪里说错了,或者讲得不好,请指出来,大家一起学习讨论下。