概述
关于Spring
Spring作为目前Java领域最热门的开发框架,是一个Java程序员最常用的框架,并且在面试中Spring也是面试官考核的重要部分。目前Spring家族已经发展的非常壮大,包括目前大火的微服务框架Spring Boot和Spring Cloud等,而这些框架都离不开Spring最早期的Spring Core,也就是Spring最核心的部分。Spring Core的核心就是IOC容器,此文着重介绍Spring IOC原理
前言
对本文的理解建立在你有Spring IOC的使用经验,如果你连玩意怎么用都还不知道,那可能理解本文相对困难
IOC原理
IOC(Inversion of Control)也就是控制反转,它本质上是一种思想,Spring IOC的设计正是利用了控制反转的思想实现,所以想要理解Spring IOC先要理解控制反转思想
1.DI依赖注入
DI(Dependency Injection)即依赖注入,想要理解IOC首选我们要理解什么是依赖注入。下面图解一下DI
未实现控制反转的依赖注入
如上图但我们设计一个行李箱时有如下步骤:设计轮子﹣>设计好轮子后根据轮子设计底盘﹣>设计好底盘后根据底盘设计箱体﹣>设计好箱体后根据箱体设计行李箱,于是就存在图示的依赖关系。
假设此时产品经理告诉我们要把轮子的尺寸加大一码,那就意味着:重新设计轮子﹣>根据新轮子重新设计底盘﹣>根据新底盘重新设计箱体﹣>根据箱体重新设计行李箱。这对于程序员来说是一件非常头秃的事,要和产品经理干架了。
咋们根据代码来看一下,依据上面设计行李箱的流程有如下代码关系:
上层类的构造器中都new了下层类的实例,如果此时我们希望轮子Tire的size字段是可变的,那代码关系就转变成下面这样:
显然,因为修改Tire导致了整个上层的每个类都需要被修改,代码可维护性很差
实现控制反转后的依赖注入
如上图但我们设计一个行李箱时有如下步骤:设计行李箱﹣>设计好行李箱后根据行李箱设计箱体﹣>设计好箱体后根据箱体设计底盘﹣>设计好底盘后根据底盘设计轮子,也就是下层类作为参数传入上层类,即控制反转实现上层控制下层。
结合实际代码看一下:
如果此时我们希望可以动态修改Tire的size只需要做如下的修改:
显然代码可维护性增强了,上层类不在需要依据底层类的变化做出修改,实现各个部分代码之间的解耦
2.IOC和DI、DL之间的关系
实现IOC控制反转的方式有两种,一种是DL依赖查找,目前已经基本被抛弃,另一种就是DI依赖注入,是当今IOC的主流实现方式,Spring就是利用DI的方式来实现IOC控制反转。
Spring的依赖注入方式有四种:
- Setter方式(Set注入)
- Constructor(构造器注入)
- Annotation(注解注入)
- Interface(接口注入)
3.依赖倒置原则、IOC、DI、IOC容器之间的关系
依赖倒置原则是一种高层模块不应该依赖于底层模块的思想,根据这种思想于是有了IOC控制反转的设计,而实现控制反转需要用到DI依赖注入的方法,Spring则依据IOC提出了容器的概念,也就是Spring IOC容器。 Spring的IOC容器管理bean的生命周期和控制bean之间的依赖注入,IOC容器有如下优点:
- 避免在各处使用new来创建类,并且可以做到统一维护
- 创建实例时不需要了解其中的细节(自动处理类之间的依赖关系,自动装配)
深入Spring IOC容器
1.Spring IOC容器工作机制
Spring IOC容器工作机制分为如下步骤:
- 读取Bean配置信息,生成bean配置注册表,配置信息包括XML配置文件,@Configuration注解的配置类,@Autowired自动注入等
- 根据bean配置注册表实例化bean
- 建立好bean实例之间的依赖关系,并且把bean实例存放IOC容器的Bean缓存池中
- 应用程序使用bean实例
2.Spring IOC核心接口
- BeanDefinition:主要用来描述Bean的定义,包括类型、属性、是否单例、是否懒加载、相关依赖等,Spring IOC容器在启动时会将我们在XML配置中或者注解的Bean解析成BeanDefinition,Spring IOC容器通过BeanDefinition对Bean进行管理和依赖装配
- BeanFactory:此接口是Spring IOC最底层核心接口,Spring IOC容器实现的架构基础,主要提供以下功能:
- 提供IOC配置机制
- 包含Bean的各种定义,便于实例化Bean
- 建立Bean之间依赖关系
- Bean生命周期控制
- ApplicationContext:建立在BeanFactory的基础之上,如果说BeanFactory是一辆汽车,那ApplicationContext就是一辆更高级的汽车拥有更多功能,它不仅仅拥有BeanFactory的能力,通过继承ResourceLoader、ApplicationEventPublisher等接口使它拥有加载资源文件和监听等能力。可以说BeanFactory构建了Spring IOC的基础,ApplicationContext在基础之上更进一步,其主要面向使用Spring的开发者
3.深入Spring IOC源码
在大致了解了Spring IOC几个关键的接口以后,我们再深入到源码当中,深层次剖析。我们知道Spring IOC处理的最重要的两件事就是管理Bean的生命周期和处理Bean之间的依赖关系,下文我们也着重深入源码研究Spring IOC容器是怎样做到这两点的
新建项目
咋们新建一个Spring Boot项目进行研究(我使用的是Spring Boot
2.2.1.RELEASE,可能由于Spring版本不同,下文的部分代码会有一些不同,但是基本没什么差异)
很简单,一个Spring Boot的启动类、一个实体类、一个配置类
实体类:
public class User {
private String username;
private String pwd;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
- 已Spring Boot启动
配置类:
@Configuration
public class Config {
@Bean
public User user(){
User user = new User();
user.setUsername("ling");
user.setPwd("123");
return user;
}
}
最后启动类:
@SpringBootApplication
public class IocDemoApplication {
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(IocDemoApplication.class, args);
User user = (User) applicationContext.getBean("user");
System.out.println(user.getUsername() + " " + user.getPwd());
// ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("");
}
}
这基本就是我们使用Spring IOC一个最基本简单的案例,在配置类中将User实体注册到容器中,在启动类里通过容器把User实例取出来。
BeanFactory初始化和注册Bean定义
咋们根据Spring Boot的启动代码来深入,先看看SpringApplication.run(IocDemoApplication.class, args)的run方法是怎样的
// SpringApplication.class
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class[]{primarySource}, args);
}
里面调用run(new Class[]{primarySource}, args),继续进入方法
// SpringApplication.class
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return (new SpringApplication(primarySources)).run(args);
}
再次调用了run(args),继续进入方法
// SpringApplication.class
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
this.configureHeadlessProperty();
SpringApplicationRunListeners listeners = this.getRunListeners(args);
listeners.starting();
Collection exceptionReporters;
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
this.configureIgnoreBeanInfo(environment);
Banner printedBanner = this.printBanner(environment);
context = this.createApplicationContext();
exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
this.refreshContext(context);
this.afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
(new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
}
listeners.started(context);
this.callRunners(context, applicationArguments);
} catch (Throwable var10) {
this.handleRunFailure(context, var10, exceptionReporters, listeners);
throw new IllegalStateException(var10);
}
try {
listeners.running(context);
return context;
} catch (Throwable var9) {
this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
throw new IllegalStateException(var9);
}
}
终于看到一个比较不一样的方法了,这个方法里大致来看就是创建了ConfigurableApplicationContext实例然后返回,我们重点关注this.refreshContext(context),进入到这个方法里面
// SpringApplication.class
private void refreshContext(ConfigurableApplicationContext context) {
this.refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
} catch (AccessControlException var3) {
;
}
}
}
这里调用了this.refresh(context),我们在进入这个方法
// SpringApplication.class
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext)applicationContext).refresh();
}
这里((AbstractApplicationContext)applicationContext).refresh()又调用了refresh()方法,进入refresh()方法看看(这是咋们的重头戏)
// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
代码到这先暂停一下,从Spring Boot的启动流程来看,显然Spring Boot启动以后使用的是ConfigurableApplicationContext这种ApplicationContext,那我们看看ClassPathXmlApplicationContext。早期Spring Boot未出现时,使用 ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("xxx")读取Spring配置文件来启动容器的方式经常被用到。我们直接找ClassPathXmlApplicationContext的构造方法
// ClassPathXmlApplicationContext.class
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super(parent);
this.setConfigLocations(configLocations);
if (refresh) {
this.refresh();
}
}
这里也调用了refresh()方法,我们点进去看一下
// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
synchronized(this.startupShutdownMonitor) {
this.prepareRefresh();
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
this.prepareBeanFactory(beanFactory);
try {
this.postProcessBeanFactory(beanFactory);
this.invokeBeanFactoryPostProcessors(beanFactory);
this.registerBeanPostProcessors(beanFactory);
this.initMessageSource();
this.initApplicationEventMulticaster();
this.onRefresh();
this.registerListeners();
this.finishBeanFactoryInitialization(beanFactory);
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
显然不论是Spring Boot启动还是通过ApplicationContext applicationContext1 = new ClassPathXmlApplicationContext("xxx")启动容器,最终都进到AbstractApplicationContext的refresh()方法中,有兴趣的同学可以看看其他类型的ApplicationContext,比如说FileSystemXmlApplicationContext的构造方法同样都调用了这个方法,所以这是容器初始化最重要的方法,是Spring IOC容器初始化的整体逻辑,接下来我们已ClassPathXmlApplicationContext容器的初始化为例,从这个refresh()方法开始入手,
先写一下refresh()方法里面大致的行为
// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
// 加上锁,防止容器被重复创建
synchronized(this.startupShutdownMonitor) {
// 为刷新准备应用上下文
this.prepareRefresh();
// 这里是关键,在这刷新创建BeanFactory,并且读取Bean的配置信息,并且注册到Bean注册表(其实就是一个 beanName-> beanDefinition 的 map),但是Bean还没有被实例化
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor
this.prepareBeanFactory(beanFactory);
try {
// 设置BeanFactory的后置处理器
this.postProcessBeanFactory(beanFactory);
// 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean的后处理器,在Bean创建过程中调用
this.registerBeanPostProcessors(beanFactory);
//对上下文的消息源进行初始化
this.initMessageSource();
// 初始化上下文中的事件机制
this.initApplicationEventMulticaster();
// 初始化其他的特殊Bean
this.onRefresh();
// 检查监听Bean并且将这些Bean向容器注册
this.registerListeners();
// 初始化所有的 singleton beans(lazy-init除外),这个非常重要
this.finishBeanFactoryInitialization(beanFactory);
// 发布容器事件,结束refresh过程
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
到这我们先说这个refresh()方法中第一个重要的地方ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(), 进入this.obtainFreshBeanFactory()看一下
// AbstractApplicationContext.class
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
this.refreshBeanFactory();
return this.getBeanFactory();
}
其实就是关闭旧的 BeanFactory (如果有),创建新的 BeanFactory,加载 Bean 定义、注册 Bean 等等(但是Bean实例化没有在这完成),并且返回了BeanFactory,这里调用了 this.refreshBeanFactory(),继续进去看一下,进入AbstractRefreshableApplicationContext这个子类看具体实现
// AbstractRefreshableApplicationContext.class
protected final void refreshBeanFactory() throws BeansException {
// 判断当前ApplicationContext是否已经有BeanFactory了,有的话销毁Bean实例和BeanFactory
if (this.hasBeanFactory()) {
this.destroyBeans();
this.closeBeanFactory();
}
try {
// 初始化一个 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = this.createBeanFactory();
// BeanFactory设置序列化
beanFactory.setSerializationId(this.getId());
// 设置 BeanFactory 的两个配置属性:是否允许 Bean 覆盖、是否允许循环引用
this.customizeBeanFactory(beanFactory);
// 使用BeanFactory加载Bean定义,就是BeanDefinition,这里是重点
this.loadBeanDefinitions(beanFactory);
Object var2 = this.beanFactoryMonitor;
synchronized(this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException var5) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
}
}
跟我写的代码注释可以看出这段代码的大致流程就是,销毁已有的Bean实例和BeanFactory,然后创建一个新的DefaultListableBeanFactory,之后到this.loadBeanDefinitions(beanFactory)加载Bean定义,这是一个抽象方法,我们进到AbstractXmlApplicationContext这个类里面的loadBeanDefinitions(beanFactory)方法实现看一下
// AbstractXmlApplicationContext.class
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 给BeanFactory 实例化一个 XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
this.initBeanDefinitionReader(beanDefinitionReader);
// 重点
this.loadBeanDefinitions(beanDefinitionReader);
}
比较简单,就是创建了一个XmlBeanDefinitionReader,给他设置了一些玩意,然后调用了重头戏this.loadBeanDefinitions(beanDefinitionReader),看这个方法
// AbstractXmlApplicationContext.class
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = this.getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = this.getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
我们进到reader.loadBeanDefinitions(configLocations)方法里看一下
// AbstractBeanDefinitionReader.class
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
String[] var3 = locations;
int var4 = locations.length;
for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
count += this.loadBeanDefinitions(location);
}
return count;
}
继续进 this.loadBeanDefinitions(location)
// AbstractBeanDefinitionReader.class
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(location, (Set)null);
}
继续this.loadBeanDefinitions(location, (Set)null)
// AbstractBeanDefinitionReader.class
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int count;
if (resourceLoader instanceof ResourcePatternResolver) {
try {
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
count = this.loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
} catch (IOException var6) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
}
} else {
Resource resource = resourceLoader.getResource(location);
count = this.loadBeanDefinitions((Resource)resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
}
这里咋们还是关心count = this.loadBeanDefinitions(resources)和count = this.loadBeanDefinitions((Resource)resource),进到XmlBeanDefinitionReader的实现里面
// XmlBeanDefinitionReader.class
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(new EncodedResource(resource));
}
继续进入loadBeanDefinitions(new EncodedResource(resource))
// XmlBeanDefinitionReader.class
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
if (!((Set)currentResources).add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
int var5;
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException var15) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var15);
} finally {
((Set)currentResources).remove(encodedResource);
if (((Set)currentResources).isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var5;
}
}
我们关注var5 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource()),进入doLoadBeanDefinitions(inputSource, encodedResource.getResource())方法
// XmlBeanDefinitionReader.class
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
Document doc = this.doLoadDocument(inputSource, resource);
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (SAXParseException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
} catch (SAXException var7) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
} catch (ParserConfigurationException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
} catch (IOException var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
} catch (Throwable var10) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
}
}
这里可以看出方法里创建了一个Document并且进到并且通过this.registerBeanDefinitions(doc, resource)把Bean注册到容器,进入这个方法
// XmlBeanDefinitionReader.class
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
int countBefore = this.getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
这里创建BeanDefinitionDocumentReader并且调用documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource))把Bean注册进容器,进这个方法的实现
// DefaultBeanDefinitionDocumentReader.class
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
this.doRegisterBeanDefinitions(doc.getDocumentElement());
}
继续进this.doRegisterBeanDefinitions(doc.getDocumentElement())
// DefaultBeanDefinitionDocumentReader.class
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = this.createDelegate(this.getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute("profile");
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(profileSpec, ",; ");
if (!this.getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + this.getReaderContext().getResource());
}
return;
}
}
}
this.preProcessXml(root);
// 重点
this.parseBeanDefinitions(root, this.delegate);
this.postProcessXml(root);
this.delegate = parent;
}
进去看
// DefaultBeanDefinitionDocumentReader.class
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)) {
this.parseDefaultElement(ele, delegate);
} else {
delegate.parseCustomElement(ele);
}
}
}
} else {
delegate.parseCustomElement(root);
}
}
this.parseDefaultElement(ele, delegate)解析default namespace下面的几个元素,进去看一下
// DefaultBeanDefinitionDocumentReader.class
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, "import")) {
this.importBeanDefinitionResource(ele);
} else if (delegate.nodeNameEquals(ele, "alias")) {
this.processAliasRegistration(ele);
} else if (delegate.nodeNameEquals(ele, "bean")) {
this.processBeanDefinition(ele, delegate);
} else if (delegate.nodeNameEquals(ele, "beans")) {
this.doRegisterBeanDefinitions(ele);
}
}
分别解析四种xml里面的标签, <import />、<alias />、<bean />、<beans />,
以<bean />为例来看,进this.processBeanDefinition(ele, delegate)
// DefaultBeanDefinitionDocumentReader.class
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException var5) {
this.getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, var5);
}
this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele)把xml文件中提取Bean信息实例化为BeanDefinition封装到BeanDefinitionHolder里面,BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.getReaderContext().getRegistry())把bdHolder里面的Bean定义注册到容器,最后this.getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder))执行容器通知,我们看看BeanDefinitionReaderUtils.registerBeanDefinition
// BeanDefinitionReaderUtils.class
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
String[] var4 = aliases;
int var5 = aliases.length;
for(int var6 = 0; var6 < var5; ++var6) {
String alias = var4[var6];
registry.registerAlias(beanName, alias);
}
}
}
先从definitionHolder里面取出beanName,然后取出对应的BeanDefinition, registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
把beanName和对应的BeanDefinition注册,最后在看一下registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())这个方法里面
// DefaultListableBeanFactory.class
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition)beanDefinition).validate();
} catch (BeanDefinitionValidationException var8) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
}
}
BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
if (!this.isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
if (existingDefinition.getRole() < beanDefinition.getRole()) {
if (this.logger.isInfoEnabled()) {
this.logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (!beanDefinition.equals(existingDefinition)) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
} else if (this.logger.isTraceEnabled()) {
this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
}
this.beanDefinitionMap.put(beanName, beanDefinition);
} else {
if (this.hasBeanCreationStarted()) {
Map var4 = this.beanDefinitionMap;
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;
this.removeManualSingletonName(beanName);
}
} else {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
if (existingDefinition != null || this.containsSingleton(beanName)) {
this.resetBeanDefinition(beanName);
}
}
到这已经到把Bean信息注册到容器的最后一步,看this.beanDefinitionMap.put(beanName, beanDefinition),其实就是把beanName和beanDefinition作为一对键值对存储到beanDefinitionMap里面。
经过漫长的过程,到这已经完成了创建BeanFactory和生成BeanDefinition,但是还没有完成Bean实例化和依赖构建。
Bean实例化和依赖构建
上文已经走到了创建创建BeanFactory和生成BeanDefinition,就是创建了容器和注册了Bean定义,接下来我们研究Bean实例的初始化和Bean之间的依赖关系是如何构建的
重新回到refresh()方法中看一下
// AbstractApplicationContext.class
public void refresh() throws BeansException, IllegalStateException {
Object var1 = this.startupShutdownMonitor;
// 加上锁,防止容器被重复创建
synchronized(this.startupShutdownMonitor) {
// 为刷新准备应用上下文
this.prepareRefresh();
// 这里是关键,在这刷新创建BeanFactory,并且读取Bean的配置信息,并且注册到Bean注册表(其实就是一个 beanName-> beanDefinition 的 map),但是Bean还没有被实例化
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
//设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor
this.prepareBeanFactory(beanFactory);
try {
// 设置BeanFactory的后置处理器
this.postProcessBeanFactory(beanFactory);
// 调用BeanFactory的后处理器,这些后处理器是在Bean定义中向容器注册的
this.invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean的后处理器,在Bean创建过程中调用
this.registerBeanPostProcessors(beanFactory);
//对上下文的消息源进行初始化
this.initMessageSource();
// 初始化上下文中的事件机制
this.initApplicationEventMulticaster();
// 初始化其他的特殊Bean
this.onRefresh();
// 检查监听Bean并且将这些Bean向容器注册
this.registerListeners();
// 初始化所有的 singleton beans(lazy-init除外),这个非常重要
this.finishBeanFactoryInitialization(beanFactory);
// 发布容器事件,结束refresh过程
this.finishRefresh();
} catch (BeansException var9) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
}
this.destroyBeans();
this.cancelRefresh(var9);
throw var9;
} finally {
this.resetCommonCaches();
}
}
}
上文我们走完了this.obtainFreshBeanFactory()这个方法,Bean的实例化和依赖构建则是在this.finishBeanFactoryInitialization(beanFactory)方法里完成,如果没有设置懒加载,这里将会完成所有singleton bean(单例)的初始化。我们进这个方法
// AbstractApplicationContext.class
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
if (beanFactory.containsBean("conversionService") && beanFactory.isTypeMatch("conversionService", ConversionService.class)) {
beanFactory.setConversionService((ConversionService)beanFactory.getBean("conversionService", ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver((strVal) -> {
return this.getEnvironment().resolvePlaceholders(strVal);
});
}
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
String[] var3 = weaverAwareNames;
int var4 = weaverAwareNames.length;
for(int var5 = 0; var5 < var4; ++var5) {
String weaverAwareName = var3[var5];
this.getBean(weaverAwareName);
}
beanFactory.setTempClassLoader((ClassLoader)null);
beanFactory.freezeConfiguration();
beanFactory.preInstantiateSingletons();
}
我们直接看最后一个方法beanFactory.preInstantiateSingletons()
// DefaultListableBeanFactory.class
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Pre-instantiating singletons in " + this);
}
List<String> beanNames = new ArrayList(this.beanDefinitionNames);
Iterator var2 = beanNames.iterator();
while(true) {
String beanName;
Object bean;
do {
while(true) {
RootBeanDefinition bd;
do {
do {
do {
if (!var2.hasNext()) {
var2 = beanNames.iterator();
while(var2.hasNext()) {
beanName = (String)var2.next();
Object singletonInstance = this.getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(() -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, this.getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
return;
}
beanName = (String)var2.next();
bd = this.getMergedLocalBeanDefinition(beanName);
} while(bd.isAbstract());
} while(!bd.isSingleton());
} while(bd.isLazyInit());
if (this.isFactoryBean(beanName)) {
bean = this.getBean("&" + beanName);
break;
}
this.getBean(beanName);
}
} while(!(bean instanceof FactoryBean));
FactoryBean<?> factory = (FactoryBean)bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
SmartFactoryBean var10000 = (SmartFactoryBean)factory;
((SmartFactoryBean)factory).getClass();
isEagerInit = (Boolean)AccessController.doPrivileged(var10000::isEagerInit, this.getAccessControlContext());
} else {
isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
}
if (isEagerInit) {
this.getBean(beanName);
}
}
}
这里不同的Spring版本可能代码不太一样,其实就是排除懒加载和abstract的bean,把所有非懒加载在和abstract的singleton bean实例化。代码通过this.getBean(beanName)就可以完成实例化,我们看这个方法,里面调用了this.doGetBean(name, (Class)null, (Object[])null, false),我们直接看doGetBean()方法
// AbstractBeanFactory.class
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {
String beanName = this.transformedBeanName(name);
Object sharedInstance = this.getSingleton(beanName);
Object bean;
if (sharedInstance != null && args == null) {
if (this.logger.isTraceEnabled()) {
if (this.isSingletonCurrentlyInCreation(beanName)) {
this.logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
} else {
this.logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
} else {
if (this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
}
if (args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
return parentBeanFactory.getBean(nameToLookup);
}
if (!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope 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, () -> {
this.beforePrototypeCreation(beanName);
Object var4;
try {
var4 = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
return var4;
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException var23) {
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", var23);
}
}
} catch (BeansException var26) {
this.cleanupAfterBeanCreationFailure(beanName);
throw var26;
}
}
先看这部分代码
String[] dependsOn = mbd.getDependsOn();
String[] var11;
// 遍历依赖
if (dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dep = var11[var13];
if (this.isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
this.registerDependentBean(dep, beanName);
try {
// 先实例化依赖,递归
this.getBean(dep);
} catch (NoSuchBeanDefinitionException var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", var24);
}
}
}
这段代码获取了bean的依赖,遍历它的依赖,并且this.getBean(dep)先实例化依赖,就这样递归直到没有依赖为止,进入下面这段代码
if (mbd.isSingleton()) {
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
这段代码调用了this.createBean(beanName, mbd, args),我们进这个方法
// AbstractAutowireCapableBeanFactory.class
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
Class<?> resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var9) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var9);
}
Object beanInstance;
try {
beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
if (beanInstance != null) {
return beanInstance;
}
} catch (Throwable var10) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var10);
}
try {
beanInstance = this.doCreateBean(beanName, mbdToUse, args);
if (this.logger.isTraceEnabled()) {
this.logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
} catch (ImplicitlyAppearedSingletonException | BeanCreationException var7) {
throw var7;
} catch (Throwable var8) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", var8);
}
}
进beanInstance = this.doCreateBean(beanName, mbdToUse, args)看
// AbstractAutowireCapableBeanFactory.class
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
Object var7 = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable var17) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if (earlySingletonExposure) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
this.addSingletonFactory(beanName, () -> {
return this.getEarlyBeanReference(beanName, mbd, bean);
});
}
Object exposedObject = bean;
try {
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable var18) {
if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
throw (BeanCreationException)var18;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
}
if (earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
String dependentBean = var12[var14];
if (!this.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 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
这个方法的内容相当多重点在于:
- instanceWrapper = this.createBeanInstance(beanName, mbd, args);完成Bean实例化
- this.populateBean(beanName, mbd, instanceWrapper)完成依赖注入
我们先看第一个方法
// AbstractAutowireCapableBeanFactory.class
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
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());
} else {
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return this.obtainFromSupplier(instanceSupplier, beanName);
} else if (mbd.getFactoryMethodName() != null) {
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
Object var8 = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {
ctors = mbd.getPreferredConstructors();
return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd);
} else {
return this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
}
}
进这个this.instantiateBean(beanName, mbd)方法看
// AbstractAutowireCapableBeanFactory.class
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(() -> {
return thisx.getInstantiationStrategy().instantiate(mbd, beanName, this);
}, this.getAccessControlContext());
} else {
beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
this.initBeanWrapper(bw);
return bw;
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
}
}
这里通过beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this)进行bean实例化,进这个方法
// SimpleInstantiationStrategy.class
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
if (!bd.hasMethodOverrides()) {
Object var5 = bd.constructorArgumentLock;
Constructor constructorToUse;
synchronized(bd.constructorArgumentLock) {
constructorToUse = (Constructor)bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
clazz.getClass();
constructorToUse = (Constructor)AccessController.doPrivileged(() -> {
return clazz.getDeclaredConstructor();
});
} else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Throwable var9) {
throw new BeanInstantiationException(clazz, "No default constructor found", var9);
}
}
}
return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
} else {
return this.instantiateWithMethodInjection(bd, beanName, owner);
}
}
这里边调用了BeanUtils.instantiateClass(constructorToUse, new Object[0])利用构造器创建了实例,到这算是完成Bean的实例化了
我们刚刚说到的两行代码:
- instanceWrapper = this.createBeanInstance(beanName, mbd, args)完成Bean实例化
- this.populateBean(beanName, mbd, instanceWrapper)完成依赖注入
我们接下来看第二行,进入第二个方法
// AbstractAutowireCapableBeanFactory.class
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 {
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var5 = this.getBeanPostProcessors().iterator();
while(var5.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var5.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (continueWithPropertyPopulation) {
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null;
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == 1 || resolvedAutowireMode == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if (resolvedAutowireMode == 1) {
this.autowireByName(beanName, mbd, bw, newPvs);
}
if (resolvedAutowireMode == 2) {
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
Iterator var10 = this.getBeanPostProcessors().iterator();
while(var10.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var10.next();
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
PropertyValues pvsToUse = ibp.postProcessProperties((PropertyValues)pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
if (pvs != null) {
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
}
PropertyValues pvs = mbd.hasPropertyValues() ? mbd.getPropertyValues() : null获取到该bean的所有属性,通过this.autowireByName(beanName, mbd, bw, newPvs)和this.autowireByType(beanName, mbd, bw, newPvs)进行依赖装配,最后this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs)配置bean实例属性值。
走到这就完成了Spring IOC容器初始化流程,处理了Bean实例的初始化和Bean之间构建依赖关系
总结
流本文为阐述Spring IOC原理,先脱离Spring介绍了IOC思想原理,然后深入Spring IOC容器分别阐述了:
- Spring IOC容器的工作机制
- Spring IOC核心接口
- 深入Spring IOC源码解读Spring IOC容器初始流程
整个Spring IOC容器初始流程源码真的挺难啃下来的,需要花点时间消化,总结一下Spring IOC容器初始流程基本如下:
- 创建BeanFactory
- 加载Bean信息,注册BeanDefinition到BeanFactory
- 通过BeanFactory的BeanDefinition注册信息实例化Bean实例
- 通过BeanFactory的BeanDefinition注册信息构建Bean之间依赖关系