文章目录
- 一、前言
- 二、前置准备
- 三、IOC容器的使用
- 四、Spring IOC源码解读
- 1. prepareRefresh源码解读
- 2. obtainFreshBeanFactory源码解读
- 3. prepareBeanFactory源码解读
- 4. postProcessBeanFactory源码解读
- 5. invokeBeanFactoryPostProcessors源码解读
- 6. registerBeanPostProcessors源码解读
- 7. initMessageSource源码解析
- 8. initApplicationEventMulticaster源码解读
- 9. onRefresh源码解读
- 10. registerListeners源码解读
- 11. finishBeanFactoryInitialization源码解读
- 12. finishRefresh源码解读
- 13. IOC容器加载失败源码解读
- 14. IOC容器销销毁源码解读
- 五、流程图
一、前言
无论你是一个经验丰富的Java-er
,还是一个Java初学者,都会听过Spring框架的大名,我在初学这个Spring框架的时候都是对这个框架当成一个工具使用,只知道这样做能够达到这样的效果,但是具体里面是怎么实现的也说不清楚,不过随着现在技术的越来越卷,我感觉有必要揭开Spring框架的内幕,深度学习领悟这一优秀的框架了!
本文是针对Spring框架中的IOC
核心功能进行源码解读的,准备好的话,那就一起出发喽
二、前置准备
本文会对Spring框架的IOC源码进行解读,推荐各位去GitHub下载一份Spring源码配合本篇文章食用更佳!
本文是针对Spring 4.0.0
的源码而编写的,不同版本源码会有差异,但整体业务逻辑不变。
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.0.0.RELEASE</version>
</dependency>
三、IOC容器的使用
首先,咱们先来复习一下Spring IOC
容器的使用。
public interface UserService {
String selectList();
}
public class UserServiceImpl implements UserService {
@Override
public String selectList() {
return "小明, 小红, 小蓝";
}
}
<?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="messageService" class="spring.ioc.UserServiceImpl"/>
</beans>
public class SpringTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
System.out.println("context 启动成功");
UserService userService = context.getBean(UserService.class);
System.out.println(userService.selectList());
}
}
从Spring IOC
的使用中,很直观就能感受到的就是Spring IOC
代替我们程序缘完成了对一个对象的new
把创建实例的工作交给了Spring IOC
,可以简化不少程序员的工作。
四、Spring IOC源码解读
对于Spring IOC
的源码,我认为必须带着“Bean存储在哪?什么时候被实例化?怎么获取的?”
这三个问题去阅读!
还是从上面的Demo代码入手阅读。
public class SpringTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
System.out.println("context 启动成功");
UserService userService = context.getBean(UserService.class);
System.out.println(userService.selectList());
}
}
在这个Demo代码中,干了三件事:
- 使用
application.xml
配置文件作为构造参数,创建了一个Spring
容器 - 从
Spring
容器中获取UserService
实例 - 调用
UserService
实例的方法
针对这三步,我合理猜测Spring
容器创建的时候就完成了Spring Bean
的注入。
接下来进入ApplicationContext context = new ClassPathXmlApplicationContext("application.xml")
源码查看是不是这样子的。
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
}
这里干了三件事:
- 调用了父类
ApplicationContext
的构造函数,并将parent
参数传递给它 - 调用
setConfigLocations
方法,将传入的配置文件路径设置到当前的ClassPathXmlApplicationContext
实例中 - 如果
refresh
为true
,则调用refresh
方法。这个方法会触发Spring容器的刷新过程,重新加载所有的bean定义
其他都不重要,重要的是refresh()
方法,这个方法会触发Spring
容器的刷新,加载Bean的定义。
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.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
}
}
下面会针对refresh()
的每一步进行解析!
1. prepareRefresh源码解读
prepareRefresh
方法主要是进行Spring
容器刷新前的一些准备工作,并不主要特别关注!
protected void prepareRefresh() {
// 记录Spring容器开始刷新的时间
this.startupDate = System.currentTimeMillis();
// 标志Spring容器刷新工作开始
synchronized (this.activeMonitor) {
this.active = true;
}
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// 初始化上下文中的占位符属性源
initPropertySources();
// 调用getEnvironment方法获取环境对象,并调用其validateRequiredProperties方法来验证必需的属性
getEnvironment().validateRequiredProperties();
}
2. obtainFreshBeanFactory源码解读
obtainFreshBeanFactory
的作用是刷新内部Bean工厂返回一个新的BeanFactory
实例。
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
2.1 refreshBeanFactory源码解读
refreshBeanFactory
是解析application.xml
配置文件并生成BeanDefinition
注册到Spring IOC
中去,具体怎么操作,请看下面org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
源码解读
protected final void refreshBeanFactory() throws BeansException {
// 如果BeanFactory已经存在,先销毁原来的BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建一个DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 设置bean是否允许覆盖 是否允许循环依赖
customizeBeanFactory(beanFactory);
// 加载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);
}
}
org.springframework.context.support.AbstractXmlApplicationContext#loadBeanDefinitions(org.springframework.beans.factory.support.DefaultListableBeanFactory)
源码如下
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 将读取XML操作交付给XmlBeanDefinitionReader,且生成的BeanDefinition注册进IOC中
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 设置Spring容器
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
initBeanDefinitionReader(beanDefinitionReader);
// 读取xml
loadBeanDefinitions(beanDefinitionReader);
}
接下来,着重看loadBeanDefinitions(beanDefinitionReader)
,深入了解如何加载BeanDefition
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 获取配置资源的数组
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
// 配置位置的路径字符串数组,以加载这些路径指定的Bean定义
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
接着看loadBeanDefinitions
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
// 只需要关注loadBeanDefinitions这个方法
count += loadBeanDefinitions这个方法(location);
}
return count;
}
org.springframework.beans.factory.xml.XmlBeanDefinitionReader#loadBeanDefinitions(org.springframework.core.io.Resource)
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
/** 省略部分代码 **/
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
继续看org.springframework.beans.factory.xml.XmlBeanDefinitionReader#doLoadBeanDefinitions
这里开始就是加载BeanDefinitions
了
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
// 因为配置文件是一个xml文件,因此将inputSource进行解析封装成一个Document
Document doc = doLoadDocument(inputSource, resource);
// 注册Bean定义
int count = registerBeanDefinitions(doc, resource);
return count;
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 创建一个DocumentReader, 负责读取和解析XML文档中的Bean定义
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
// 记录加载Bean之前容器的Bean数量
int countBefore = getRegistry().getBeanDefinitionCount();
// 注册Bean
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#registerBeanDefinitions
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
// 从根元素开始遍历
doRegisterBeanDefinitions(doc.getDocumentElement());
}
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
// 创建一个新的BeanDefinitionParserDelegate对象,这个对象将用于解析XML中的bean定义
this.delegate = createDelegate(getReaderContext(), root, parent);
// 解析Bean定义之前执行一些预处理操作,Spring框架并没有给出实现类, 属于一种扩展点
preProcessXml(root);
// 重点!!加载Bean定义
parseBeanDefinitions(root, this.delegate);
// 解析Bean定义之后执行一些后处理操作,Spring框架也并没有给出实现类, 属于一种扩展点
postProcessXml(root);
this.delegate = parent;
}
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
的作用是根据XML配置文件的标签的不同,进行不同的处理
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)) {
parseDefaultElement(ele, delegate);
}
else {
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
/**
* 根据标签不同进行不同的操作,这里重点介绍processBeanDefinition方法
**/
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)) {
// 加载bean
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#processBeanDefinition
这个方法是将Bean定义注册进容器中
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 将XML元素解析成BeanDefinitionHolder对象
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 对Bean进行适当装饰
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 将Bean定义注册进容器中
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 触发注册时间
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
debug
进org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition
方法,看看是如何进行注册的
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// 获取Bean定义的名字
String beanName = definitionHolder.getBeanName();
// 注册Bean定义
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// 获取别名
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 根据BeanName获取BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
// bean已经存在 进行一些操作,感兴趣自己去看源码
}
else {
// BeanName不存在
if (hasBeanCreationStarted()) {
// Cannot modify startup-time collection elements anymore (for stable iteration)
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
else {
// 将beanName与beanDefinition放至beanDefinitionMap中
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
}
到这里BeanDefinition
的注册就基本完成了,主要是以下这些步骤:
- 将XML文件包装成一个
Document
对象 - 利用
BeanDefinitionDocumentReader
解析Document
- 从XML的root进行遍历,针对不同标签
import、bean、beans
等进行不同的处理 - 就
bean
标签而言,在parseBeanDefinitionElement
方法中将bean
标签的组装成一个BeanDefinitionHolder
- 调用
BeanDefinitionRegistry
的registerBeanDefinition
进行BeanDefinition
注册 - 检查
beanName
是否已经注册,如果没有注册则将该BeanDefinition
注册进org.springframework.beans.factory.support.DefaultListableBeanFactory#beanDefinitionMap
中去 - 如果存在别名,也可以进行别名注册。
3. prepareBeanFactory源码解读
prepareBeanFactory
方法主要是完善beanFactory
, 对其进行一些属性填充
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 配置类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 配置表达式解析器, 用于解析Spring表达式
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
// 注册属性编辑注册器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加BeanPostProcessor, 用于处理实现了ApplicationContextAware接口的Bean
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略特定的依赖接口
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// 注册可解析的依赖
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 检查和准备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()));
}
// 注册环境相关bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
4. postProcessBeanFactory源码解读
没有给出实现,交由子类去实现
5. invokeBeanFactoryPostProcessors源码解读
invokeBeanFactoryPostProcessors
的作用是调用所有注册的BeanFactoryPostProcessor
实例
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
6. registerBeanPostProcessors源码解读
registerBeanPostProcessors
的作用是实例化BeanPostProcessor
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
7. initMessageSource源码解析
initMessageSource
方法主要是为了初始化Spring框架中的MessageSource
组件——Spring的国际化
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isDebugEnabled()) {
logger.debug("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
8. initApplicationEventMulticaster源码解读
initApplicationEventMulticaster
的作用是初始化事件广播器,相对比较简单
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isDebugEnabled()) {
logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate ApplicationEventMulticaster with name '" +
APPLICATION_EVENT_MULTICASTER_BEAN_NAME +
"': using default [" + this.applicationEventMulticaster + "]");
}
}
}
9. onRefresh源码解读
在Spring中没有给出实现,属于一个模板方法,但是在SpringBoot中启动了Web服务器
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
10. registerListeners源码解读
registerListeners
的作用是为了注册监听器,方便接收广播事件
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 lisName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(lisName);
}
}
11. finishBeanFactoryInitialization源码解读
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化上下文转化服务,主要用于类型转化、数据转换等等
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));
}
// 提前实例化LoadTimeWeaverAware的类
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 在BeanFactory初始化完成后,不再需要临时类加载器,因此将其设置为null。
beanFactory.setTempClassLoader(null);
// BeanFactory将不再期望对Bean的定义进行进一步的更改,这有助于提高性能。
beanFactory.freezeConfiguration();
// 实例化所有非延迟初始化的单例Bean。这意味着所有剩余的单例Bean都将被创建,即使它们尚未被显式请求。
beanFactory.preInstantiateSingletons();
}
11.1 preInstantiateSingletons源码解读
这里的preInstantiateSingletons
是经过简化的
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
// 获取Bean定义
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 需要实例化的bean不是抽象的 并且是单例 并且不属于懒加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 获取工厂Bean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
// 为true表示需要被立刻实例化
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 {
// 不属于工厂Bean,就可以立即创建Bean
getBean(beanName);
}
}
}
}
这里干了这几件事情:
- 获取当前所有Bean定义的BeanName集合
- 遍历BeanName集合,进行判断
- 如果该Bean是一个
FactoryBean
,则检查它是否实现了SmartFactoryBean
接口,调用isEagerInit
方法来确定是否需要立即初始化。 - 如果不是
FactoryBean
,立刻实例化
- 如果该Bean是一个
12. finishRefresh源码解读
finishRefresh
的完成容器的启动,清除上下文,初始化生命周期处理器,并发送刷新事件
protected void finishRefresh() {
// 初始化生命周期处理器
initLifecycleProcessor();
// 刷新事件传播到生命周期处理器。
getLifecycleProcessor().onRefresh();
// 创建并发布一个ContextRefreshedEvent事件,通知所有监听器应用程序上下文已经刷新完成
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
13. IOC容器加载失败源码解读
当Spring容器启动的时候出现异常后会走catch
流程,首当其冲就是调用destroyBeans
,也就是销毁所有bean,让JVM能够回收内存。
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
public void destroySingletons() {
if (logger.isTraceEnabled()) {
logger.trace("Destroying singletons in " + this);
}
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
String[] disposableBeanNames;
synchronized (this.disposableBeans) {
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();
}
public void destroySingletons() {
super.destroySingletons();
updateManualSingletonNames(Set::clear, set -> !set.isEmpty());
clearByTypeCache();
}
接着将IOC容器的活跃状态设置为false
protected void cancelRefresh(BeansException ex) {
synchronized (this.activeMonitor) {
this.active = false;
}
}
14. IOC容器销销毁源码解读
当IOC容器被关闭的时候,会调用close
方法
public void close() {
synchronized (this.startupShutdownMonitor) {
doClose();
}
}
在close
方法调用了doClose
方法
protected void doClose() {
boolean actuallyClose;
synchronized (this.activeMonitor) {
actuallyClose = this.active && !this.closed;
this.closed = true;
}
// 发布容器关闭事件
publishEvent(new ContextClosedEvent(this));
getLifecycleProcessor().onClose();
// 销毁Bean,上面有解释
destroyBeans();
// 将beanFactory设置为null,方便JVM回收
closeBeanFactory();
synchronized (this.activeMonitor) {
this.active = false;
}
}
五、流程图
暂时略~后面有时间再补充哈哈哈