SpringIOC 源码解析
本篇主要和大家一起来看看spring中ioc的源码,从bean的定义到初始化、实例化的过程。我们都说spring其实就是个HashMap,那么到底底层是怎么管理beans的呢,还有我们想知道为什么使用了注解[@Component]之后,spring就会自动将这个类加入到容器。在这篇文章我尽量去解答这个疑问,有错漏的请大家指正。
前言
工欲善其事必先利其器,如今做java的不可能跳过Spring,遇到什么困难都不要怕,勇敢的面对它。
在阅读本篇之前,我假定大家都有一定的spring基础,至少使用配置文件的方式搭建一个spring工程没有问题。本篇对应的spring版本是5.2.5.RELEASE
,查看工具是IDEA。
SpringIOC其实要强调的就2个部分:
- 读取配置,得到BeanDefinition
- 实例化、初始化Bean
还有3个比较重要的接口,他们的名字都比较类似【spring的方法和类名是真的长,但是也是超级规范,见名知意】
- BeanPostProcessor
- BeanFactoryPostProcessor
- BeanDefinitionRegistryPostProcessor
这些单词我们在后面的源码中将会经常见到,大家一定要注意区分清楚。名称一旦看混了,就容易晕了。
准备
很多人其实还是比较想看源码的,但是又觉得无从下手,我们打断点应该从哪里开始呢?
任何java程序的入口一定是main
方法,最简单的SpringBoot项目的主类不就是main方法嘛。当然我们这里不写main,我们写测试类。
先来一些基本代码,大家直接copy我的代码,然后运行出结果就好了。只是做个演示
pom引入spring-context包,junit包。
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
</dependencies>
我们看看context包的内容
spring-context包以及包含了关键的几个:aop、beans、context、core、jcl、expression,这里jcl其实就是common-logging包,改了个名字。
创建几个基本的bean实现一些接口
public class MyBean implements InitializingBean, DisposableBean {
@Override
public void destroy() throws Exception {
// bean销毁时调用此方法
System.out.println("MyBean >>> destroy");
}
@Override
public void afterPropertiesSet() throws Exception {
// bean赋值时调用
System.out.println("MyBean >>> afterPropertiesSet");
}
}
public class MyBeanDefinitionRegistationPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanDefinitionRegistry >>> 当前 beans:" + registry.getBeanDefinitionNames().length);
for (String beanDefinitionName : registry.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
System.out.println("----------");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanFactory >>> 当前 beans:" + beanFactory.getBeanDefinitionNames().length);
}
}
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("MyBeanFactoryPostProcessor >>> postProcessBeanFactory >>> 当前有定义的 bean:" + beanFactory.getBeanDefinitionNames().length);
}
}
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " >>> MyBeanPostProcessor >>> Before 初始化 ");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " >>> MyBeanPostProcessor >>> After 初始化 ");
return bean;
}
}
public class Red {
private String color;
}
注意我们使用的是xml的方式配置bean,没有加注解。
下面定义一个spring的bean文件,beans.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean class="top.ybq87.Red" id="red"/>
<bean id="myBean" class="top.ybq87.MyBean"/>
<bean class="top.ybq87.MyBeanDefinitionRegistationPostProcessor" id="myBeanDefinitionRegistationPostProcessor"/>
<bean class="top.ybq87.MyBeanFactoryPostProcessor" id="myBeanFactoryPostProcessor"/>
<bean class="top.ybq87.MyBeanPostProcessor" id="myBeanPostProcessor"/>
</beans>
然后编写一个测试方法
@Test
public void test() {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:beans.xml");
System.out.println("applicationContext:" + applicationContext);
applicationContext.start();
applicationContext.close();
}
这里获取的是ClassPathXmlApplicationContext,为了使用start方法和close方法,主要是测试bean的销毁。
执行测试方法后的打印:
MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanDefinitionRegistry >>> 当前 beans:5
red
myBean
myBeanDefinitionRegistationPostProcessor
myBeanFactoryPostProcessor
myBeanPostProcessor
----------
MyBeanDefinitionRegistationPostProcessor >>> postProcessBeanFactory >>> 当前 beans:5
MyBeanFactoryPostProcessor >>> postProcessBeanFactory >>> 当前有定义的 bean:5
red >>> MyBeanPostProcessor >>> Before 初始化
red >>> MyBeanPostProcessor >>> After 初始化
myBean >>> MyBeanPostProcessor >>> Before 初始化
MyBean >>> afterPropertiesSet
myBean >>> MyBeanPostProcessor >>> After 初始化
applicationContext:org.springframework.context.support.ClassPathXmlApplicationContext@4fccd51b,...
MyBean >>> destroy
要开始看源码了,跟我做,一定要一遍看文章,一遍打开源码查看!
开始
debug进入之后,我们首先找到构造方法:
ClassPathXmlApplicationContext#138行
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
// 根据提供的路径,处理成配置文件数组(以分号、逗号、空格、tab、换行符分割),非重点
setConfigLocations(configLocations);
if (refresh) {
// 重点方法
// 为什么是 refresh(),而不是 init() 这种名字的方法。
// 因为 ApplicationContext 建立起来以后,其实我们是可以通过调用 refresh() 这个方法重建容器的,
// refresh() 会将原来的 ApplicationContext 销毁,然后再重新执行一次初始化操作。
refresh();
}
}
进入refresh()
方法,使用IDEA快捷键command + t,选择AbstractApplicationContext。
完整方法速览
AbstractApplicationContext#519行
,因为我加了注释,所以行数可能不一定和大家一样。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 刷新前的预处理工作.记录下容器的启动时间、标记“已启动”状态、处理配置文件中的占位符.
// 然后给出一个空的方法,交给子类实现, 子类去设置一些自定义的系统属性. 然后就没了.
prepareRefresh();
// 2. 重点讲解
// 创建 BeanFactory 对象【已经实例化了BeanFactory】,将配置文件中定义的 bean 解析为 BeanDefinition 然后存储到 beanDefinitionMap中
// 一个 bean 就是一个 BeanDefinition,目前为止 Bean 还没有初始化,只是将它们的定义信息获取到了。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 设置 BeanFactory 的一些属性. 添加几个BeanPostProcessor, 然后手动注册几个特殊的bean
prepareBeanFactory(beanFactory);
try {
// 4. BeanFactory 准备工作完成后, 进行的后置处理工作. 方法是空的, 交给子类重写实现
// 实现了 BeanFactoryPostProcessor 接口的类,会重写 postProcessorBeanFactory方法
postProcessBeanFactory(beanFactory);
// 5. 回调上一步 BeanFactoryPostProcessor 子类重写的postProcessBeanFactory方法
// 执行了,执行了,执行了,但是还没有创建 bean
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册 BeanPostProcessor 的实现类, 是 Bean 的后置处理器; 用来拦截 bean 的创建过程;
// 还记得我在文章开头说的,3个比较相似的 PostProcessor 嘛?到这里就全部出现了。
// 当前过程只是注册, 还没有执行
// BeanPostProcessor 接口有2个 方法:
// postProcessBeforeInitialization 和 postProcessAfterInitialization 分别会在 Bean 初始化之前和初始化之后得到执行
// 注意,这里只是注册,只是注册,不执行,不执行,不执行
registerBeanPostProcessors(beanFactory);
// 7. 初始化 messageSource 组件 ; 负责 国际化, 消息绑定, 消息解析,不是重点
initMessageSource();
// 8. 初始化事件派发器,
initApplicationEventMulticaster();
// 9. 此方法留给子类实现的, 在容器刷新的时候, 加入一些自定义方法. 这个方法我们在之后分析时还可能遇到
onRefresh();
// 10. 将监听器 ApplicationListener 注册进来
registerListeners();
// 11. 重点讲解,初始化 所有剩下的没有设置懒加载的单实例 Bean,到这里,才是真正的实例化 Bean
// 注意这是说的初始化,Initialization:初始化,
finishBeanFactoryInitialization(beanFactory);
// 12. 最后完成
finishRefresh();
} catch (BeansException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
} finally {
resetCommonCaches();
}
}
}
上面的12个方法就是我们今天的全部内容部分,我将会对每个方法进行详细的讲解,当然如果你对某个部分感兴趣也可以直接跳到对应的编号。
1. prepareRefresh()
进入方法,这个不过多介绍,看注释就知道了。
protected void prepareRefresh() {
// Switch to active.
//记录容器启动时间
this.startupDate = System.currentTimeMillis();
// 容器是否关闭
this.closed.set(false);
// 容器是否激活
this.active.set(true);
// 1.1 初始化一些属性设置, 此方法是空的, 说明是里给子类来实现,从而加入一些自定义属性.
initPropertySources();
// 1.2 属性校验, 对系统环境或者是自定义属性进行校验.
getEnvironment().validateRequiredProperties();
// 1.3 然后new了一个list,用来保存容器中一些早期的事件, 在多播器可用时发布事件, 什么是事件,后面我们再看.
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2. obtainFreshBeanFactory()
这个方法首先创建一个BeanFactory对象,然后进行 BeanDefinition 的解析和加载的,bean 的定义信息可以从xml配置文件来,也可以从注解的方式读取,或者从文件获取。经过这个方法之后,spring 就得到了所有的 BeanDefinition【bean的定义信息被封装为BeanDefinition对象,以后我们看到BeanDefinition就知道是bean的定义信息】,然后存储到 BeanFactory.beanDefinitionMap
属性中。这里出现了第一个ConcurrentHashMap。
查看obtainFreshBeanFactory()
方法的源码
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 2.1 这个是具体创建的方法,由子类实现, 我们查看 AbstractApplicationContext 的几个子类
// GenericApplicationContext 中的实现: 什么也没做,就是初始化了一个 DefaultListableBeanFactory beanFactory, 并设置了一个序列化的id
// AbstractRefreshableApplicationContext 中的实现: 先看是否有BeanFactory了,有就销毁其中的bean,然后关闭BeanFactory;然后重新创建BeanFactory,初始化一些BeanDefinition
refreshBeanFactory();
// 2.2 上一步创建了 BeanFactory 之后,这里获得 BeanFactory 初始化对象[ConfigurableListableBeanFactory]类型 并返回
return getBeanFactory();
}
2.1 refreshBeanFactory()
创建 BeanFactory 实例,我们快捷键command + t 看到有2个子类,其实他们都是创建一个 DefaultListableBeanFactory类型的BeanFactory对象。为什么是DefaultListableBeanfactory类型的呢?后面解答
AbstractRefreshableApplicationContext#124行
方法中的定义
@Override
protected final void refreshBeanFactory() throws BeansException {
// 是否已有 BeanFactory
if (hasBeanFactory()) {
// 销毁原有的 bean
destroyBeans();
// 关闭工厂
closeBeanFactory();
}
try {
// 创建新的 BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 设置 序列化id
beanFactory.setSerializationId(getId());
// 设置 BeanFactory的2个配置属性, 是否允许bean覆盖,是否允许循环引用
customizeBeanFactory(beanFactory);
// 加载bean到BeanFactory中, 他是一个抽象方法, 交由子类实现. 可以加载一些我们自定义的 BeanDefinition
// 看看他的几个子类: 是不是很熟悉, 假设我们写了一个 beans.xml, 里面定了很多的 <bean>,就是在这里进行解析的
// FileSystemXmlApplicationContext: 从文件系统加载配置类
// ClassPathXmlApplicationContext: 从classpath加载配置文件
// XmlWebApplictaionContext:
// AnnotationConfigWebApplicationContext: 以注解的方式加载配置的bean
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
进入 loadBeanDefinitions(beanFactory)
方法,我们选择XmlWebApplicationContext
,
2.1.1 loadBeanDefinitions
XmlWebApplicationContext#82行
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
// 实例化一个 XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
// 初始化 XmlBeanDefinitionReader ,给子类重写用的
initBeanDefinitionReader(beanDefinitionReader);
// 重点部分
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();
if (configLocations != null) {
for (String configLocation : configLocations) {
// 看这里
reader.loadBeanDefinitions(configLocation);
}
}
}
AbstractBeanDefinitionReader#195行
@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return loadBeanDefinitions(location, null);
}
这个方法我们找到
int count = loadBeanDefinitions(resources);
然后
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
// 每个文件是一个 resource
for (Resource resource : resources) {
// 这个关键方法进入,XmlBeanDefinitionReader 方法 309 行
count += loadBeanDefinitions(resource);
}
return count;
}
我们在XmlBeanDefinitionReader#340行
找到方法
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
// 进入方法看到如下:我们以xml文档为例的,所以这里就是将xml文档解析为一个document
// 转为了 document 对象
Document doc = doLoadDocument(inputSource, resource);
// 继续分解
int count = registerBeanDefinitions(doc, resource);
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 看到了熟悉的 registerBeanDefinitions , 进入此方法
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
// 返回从当前配置文件加载了多少数量的 Bean
return getRegistry().getBeanDefinitionCount() - countBefore;
}
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
doRegisterBeanDefinitions(doc.getDocumentElement());
}
DefaultBeanDefinitionDocumentReader#121行
进入方法定义
protected void doRegisterBeanDefinitions(Element root) {
// BeanDefinitionParserDelegate 解析委托类, 负责解析 bean 的定义
// 为什么定义为 parent, 因为 <beans> 节点里面 还可以定义 <beans> 的,所以这里可以递归
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
// 获取 <beans profile="dev"> 这个里面的 profile 定义
// 可以依据配置的环境加载不同的 bean , 不是当前环境的跳过不加载.
// 比如设定当前是 test 环境 ;[springboot 可以通过 spring.profile.active:dev指定, 或者配置文件<beans profile="dev">],
// 但是你定义的 <beans> 节点 profile = dev, 那么就不会去加载这个节点下的bean
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
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;
}
}
}
// 钩子 模板方法吧
preProcessXml(root);
// 重点
parseBeanDefinitions(root, this.delegate);
// 钩子
postProcessXml(root);
this.delegate = parent;
}
查看parseBeanDefinitions
方法
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// default节点: <import />、<alias />、<bean />、<beans />
// spring 默认只有4个默认标签,其他的标签都属于自定义标签。比如<tx:annotation-driven/>、注解扫描标签<context:component-scan/>
// 关于自定义标签的解析,我在文末的附录中讲解下。这里我们还是看默认的标签解析。
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);
}
}
方法parseDefaultElement
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
// import 标签处理
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);
}
}
processBeanDefinition
方法
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 将 bean 节点解析,然后封装为 BeanDefinitionHolder 对象,这个对象我们以后还会经常见到的。
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// 自定义属性解析
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 将 BeanDefinition 注册到 BeanFactory中,其实就是将bean的定义信息存放到map。
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
// bean 注册完毕,发送事件.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
方法调用BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry())
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
// 看到了熟悉的东西了, 注册BeanDefinition,这个方法以后会经常见到。
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
如果大家感兴趣的话可以继续探究一下这个registry.registerBeanDefinition
方法,她主要是判断bean是否允许覆盖,然后将 BeanDefinition 存入到 beanDefinitionMap 中。
到这里我们第一个重点部分就分解完了,其实说起来很简单,就是解析bean,然后变为 BeanDefinition对象存到BeanFactory中。
2.2 getBeanFactory()
将上一步创建的 BeanFactory 对象返回,最后得到了 ConfigurableListableBeanFactory类型的 BeanFactory 对象。至此我们的BeanFactory创建完毕。
3.prepareBeanFactory(beanFactory)
这个方法主要是给BeanFactory设置一些初始属性,加入了一个 BeanPostProcessor,然后加入了一些自动注入的属性。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 3.1 存放类加载器, 设置为加载当前applicationcontext类的类加载器.
// BeanFactory 得到了 BeanDefinition, 那么为了将定义转为真正的实例,就需要类加载器了.
beanFactory.setBeanClassLoader(getClassLoader());
// 3.2 支持的表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 3.3 添加一个 BeanPostProcessor 后置处理器, 不明白什么意思的先跳过这里,往下继续
// 更多的 BeanPostProcessor 的注册是在 第 6.步
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 3.4 设置忽略的自动装配的Aware接口, 某个 Bean 依赖于下面的几个接口的实现类,在自动装配的时候忽略他们, Spring 会通过其他方式来处理这些依赖,这里也不是重点,
// 参考: https://blog.csdn.net/qq_36951116/article/details/99587519
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 3.4 设置可以用于自动装配的, 用户可以在自定义 Bean 中, 直接用过 @Autowired 注入下面的属性 不需要实现接口
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 3.5 添加 BeanPostProcessor [ApplicationListenerDetector], 注册 事件监听器,spring在各个重要节点都会发布一些事件,这里就是创建监听,当事件发生时进行处理。后面会看到的,当然也不是重点部分。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 3.6 添加 编译时的 AspectJ 支持, 此部分我们不讨论
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 3.7 给容器注册一些 默认组件.
// Environment 环境属性 ConfigurableEnvironment
// systemProperties 系统属性, 一个 map
// systemEnvironment 系统环境变量, 一个 map
// 可以直接使用 @Autowired 使用, 比如
// @Autowired
// Map<String, Object> systemProperties;
// 就可以直接使用这个属性了。
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(beanFactory)
这个方法是留给子类进行拓展的,还记得我们上面写的几个测试方法嘛?
MyBeanDefinitionRegistationPostProcessor
和MyBeanFactoryPostProcessor
,他们都实现了BeanFactoryPostProcessor接口【BeanDefinitionRegistryPostProcessor是继承了BeanFactoryPostProcessor接口】。
这里就是spring给用户提供的一个切入口,用户在 Bean 初始化之前可以进行一些自己的操作,比如注册一个自定义的 BeanDefinition。这个方法有个BeanFactory参数,各种bean的定义信息都可以获取,修改
我们上面的2个类就打印了一些BeanDefinition的信息,但是目前 Bean 其实都还没有实例化
。
5.invokeBeanFactoryPostProcessors(beanFactory)
专门负责回调上一步中被重写的 postProcessorBeanFactory
方法。
BeanFactoryPostProcessor接口有一个子接口BeanDefinitionRegistryPostProcessor,这是spring官方大量使用的一个接口,专门用于动态注册Bean。此方法优先执行 BeanDefinitionRegistryPostProcessor 的 postProcessorBeanFactory方法,然后再执行BeanFactoryPostProcessor的postProcessorBeanFactory方法。
这点可以从我们的2个测试类的打印结果看到,大家仔细观察一下。我们先看源码
AbstractApplicationContext#774行
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 5.1 先去 getBeanFactoryPostProcessors() 获取所有的BeanFactoryPostProcessor, 进入 invokeBeanFactoryPostProcessors
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// aspectj相关,略过
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
我们看PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors方法。是不是觉得有点眼熟,之前我们查看解析xml文件,将bean的定义转为BeanDefinition时,也接触到了一个BeanDefinitionParserDelegate,委托解析类。后面还会遇到他的,先有个印象。
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 存放processor
Set<String> processedBeans = new HashSet<>();
// 判断 BeanFactory 是否是 BeanDefinitionRegistry 类型的
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 循环 beanFactoryPostProcessors, 第一次进入时 beanFactoryPostProcessors.size == 0, 所以循环会跳过
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 5.1.1 先拿到所有 实现了 BeanDefinitionRegistryPostProcessor 接口的 postprocessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 然后循环这些 PostProcessor
for (String ppName : postProcessorNames) {
// 得到实现了 PriorityOrdered 优先级接口的,
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 回调 postProcessBeanDefinitionRegistry 方法,还记得我们定义的MyBeanDefinitionRegistationPostProcessor这个类嘛?
// 这里就是回调它的重写的postProcessBeanDefinitionRegistry
// invokeBeanDefinitionRegistryPostProcessors 方法查看下内容,其实就是做方法调用。
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 5.1.2 然后查询实现了 Ordered 接口的
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 回调 postProcessBeanDefinitionRegistry(registry)
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
boolean reiterate = true;
while (reiterate) {
reiterate = false;
// 5.1.3 最后, 找到没有实现任何优先级或者顺序接口的 BeanDefinitionRegistryPostProcessor
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);
// 回调 postProcessBeanDefinitionRegistry(registry)
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 5.1.4 之前是执行的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法
// 现在执行 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法.
// 还记得BeanDefinitionRegistryPostProcessor接口有2个方法要重写嘛?上面只是调用了postProcessBeanDefinitionRegistry,但是还有一个postProcessBeanFactory方法,就在这里回调了。
// 我们也可以从我们的测试代码的打印中看到这个现象,postProcessBeanDefinitionRegistry方法先被调用,之后才打印的postProcessBeanFactory
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
/* 上面只是回调了实现 BeanDefinitionRegistryPostProcessor 接口的方法,下面是回调实现了 BeanFactoryPostProcessor 接口的方法,其实流程是一样的。先按照有优先级的调用,然后是有order的,最后是没有任何优先级的。 */
// 5.1.5 现在执行 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor 流程一样
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
} else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// 执行 postProcessBeanFactory 方法(时刻注意,这个方法是子类继承接口然后重写的接口的方法,执行这个方法只是做了些其他操作,还没有创建 bean)
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
这个方法看起来复杂,其实结构都很规整,就是调用第4步,用户重写的 BeanFactoryPostProcessor 的方法。有优先级的就按照优先级的调用。
目前我们的Bean还是没有初始化。
6. registerBeanPostProcessors(beanFactory)
注意,这里是注册,并没有执行,不执行,不执行,不执行
,进入方法
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
我们又看到了熟悉的Delegate
方法调用,
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 6.1 获取所有的 实现了 BeanPostProcessor 接口的实现类; 不同类型的 BeanPostProcessor 在bean的创建前后执行时机不一样.
// BeanPostProcessor 的子接口: 大家可以自己去写方法实现一下这些结构,然后打印看看执行的时机。
// DestructionAwareBeanPostProcessor : 用于定义在bean销毁前执行方法
// InstantiationAwareBeanPostProcessor : (有不同的方法,)实例化bean之前,实例赋值之前,
// MergedBeanDefinitionPostProcessor : 实例化Bean之后就执行这个,
// SmartInstantiationAwareBeanPostProcessor :
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// 略过
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 下面开始重点部分,不过我们之前在 5. 步的时候也看到了类似的结构,
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
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);
}
}
// 后置处理器都有优先级 和 顺序
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
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);
// Now, register all regular BeanPostProcessors.
// 最后注册没有任何优先级的接口的 BeanPostProcessor
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 最终 注册 internalPostProcessors 中的 BeanPostProcessor
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// 最后 注册一个 ApplicationListenerDetector ,
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
7. initMessageSource()
8. initApplicationEventMulticaster()
进入方法
protected void initApplicationEventMulticaster() {
// 8.1 获取所有的 BeanPostProcessor
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
// 8.2 获取 applicationEventMulticaster
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
} else {
// 8.3 没有 applicationEventMulticaster 这个 ,那么就自动创建一个 SimpleApplicationEventMulticaster 类型的 ApplicationEventMulticaster
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
// 8.4 然后自动注册到 BeanFactory, 以后其他组件可以自动注入这个 applicationEventMulticaster 组件了.
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
当然不是重点,只是知道有个东西就好了。
9. onRefresh()
10. registerListeners()
注册监听器,监听器需要实现 ApplicationListener 接口,大家自己写一个实现类试试看。
protected void registerListeners() {
// Register statically specified listeners first.
// 10.1 从容器得到已有的 ApplicationListener 组件, 然后加入派发器
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 10.2 然后查询 ApplicationListener 接口的子类,加入到派发器
// 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);
}
// 10.3 派发之前产生的事件,
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
11. finishBeanFactoryInitialization(beanFactory)
下面是重点内容,到这里我们发现spring的结构真的写的太好了,一层一层的很清晰,之前看dubbo的源码时,就被它绕晕了。废话不多说,直接上源码
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 类型转换器服务, 很实用的,而且可能经常用到的功能。
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
// 最实用的场景就是用来将前端传递过来的参数,与Controller方法上的参数进行格式匹配.
// 比如前端传递一个 String, 后端可以使用 Date 接收,那么就用到这个 conversionService
// 这里不过多的展开,大家有兴趣的可以google下,手动滑稽
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 值解析器, 方便的实现读取配置文件的属性,如果你不懂,就跳过
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 看到 LoadTimeWeaverAware 你第一眼应该想到的应该是 aspectj,不是我们的重点
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// 停止使用 用于类型匹配的临时类加载器
beanFactory.setTempClassLoader(null);
// 冻结所有的 Bean 定义, 也就是说已经注册的 BeanDefinition 将不能被修改或者后置处理
// 同时肯定不希望我正要实例化bean的时候,再注册进来一些bean定义啥的.不就没完没了了。
beanFactory.freezeConfiguration();
// 11.1 开始实例化剩下的单例bean
beanFactory.preInstantiateSingletons();
}
11.1 beanFactory.preInstantiateSingletons()
依次进入方法
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 11.1.1 得到所有的bean定义信息. beanDefinitionNames 保存了所有的 beanNames
// 还记得 BeanDefinition 是在什么时候获取到的嘛?
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 11.1.2 循环 beanNames, 进行初始化,创建对象.
for (String beanName : beanNames) {
// 得到定义信息, 合并父 Bean 中的配置, 因为 beans节点有一个参数 parent,这里不展开,大家感兴趣请google,不知道不影响后面的了解。
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非抽象, 非懒加载, 且是单实例的. 才进行下面的解析。
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 11.1.3 判断这个bean是否是 实现了 FactoryBean 接口的bean, 如果是, 那么就调用 FactoryBean 的 getObject 得到 bean
if (isFactoryBean(beanName)) {
// 注意这里加了一个前缀 & , 还是记得如果要获得 FactoryBean 这个对象本身么
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 实现了 FactoryBean 接口的
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
// 是否是 SmartFactoryBean 的实现
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 {
// 11.1.4 不是 FactoryBean 的话, 调用 doGetBean 初始化对象,第二次看到
// 这个getBean就是我们一般写测试方法时, applicationContext.getBean("xx"); 这个方法
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
// 11.1.5 初始化 bean 之后, 调用这个后置处理器. 如果 bean 实现了 SmartInitializingSingleton 接口, 回调 afterSingletonsInstantiated
// 这里就可以体会到 spring 多么的开放。
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();
}
}
}
}
11.1.4 getBean(beanName)
上面的方法分析下来,getBean(beanName)这个方法最重要。
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
进入在AbstractBeanFactory#241行
,返回一个已经实例化好的对象。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取到真正的 beanName, 因为 bean 的调用有2种:
// factoryBean(前面有'&'符号的),
// 还有使用别名来获取 bean 的,
// 这个方法就是获取到最终的真实的 beanName
final String beanName = transformedBeanName(name);
// 方法返回值先定义出来
Object bean;
// 11.1.4.1 是否在缓存中已经有这个单实例 bean 实例,
// 是从 singletonObjects 属性中获取, 她是一个 ConcurrentHashMap, 保存了所有的单实例对象, 看看,之所以说springioc就是个map,这就是证据啊,所有的单例bean都存在这个map中。
// 在DefaultListableBeanFactory中有定义各种map,
// private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
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 的话, 就要调用 getObject 返回它创建的那个实例对象.
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// 11.1.4.2 缓存中拿不到, 开始创建对象流程
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 11.1.4.3 得到 BeanFactory, 因为对象都是从 BeanFactory 创建的
BeanFactory parentBeanFactory = getParentBeanFactory();
// 父工厂, springmvc 整合时才有父工厂,目前没有的. 略过
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
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);
}
}
if (!typeCheckOnly) {
// 11.1.4.4 标记当前的 bean 已经创建
markBeanAsCreated(beanName);
}
// ************* 开始创建 bean *************
try {
// 11.1.4.5 先得到 BeanDefinition bean 的定义信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 11.1.4.6 得到当前 bean 所依赖的其他 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 + "'");
}
// 注册依赖的 bean
registerDependentBean(dep, beanName);
try {
// 然后先创建这些依赖的 bean
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 11.1.4.7 单实例的创建开始, 我们这里只讨论单例,多例的大家有空自己研究下,其实差不多。
if (mbd.isSingleton()) {
// 注意 getSingleton()这个方法,后面细看,先继续。
sharedInstance = getSingleton(beanName, () -> {
try {
// 11.1.4.7.1 调用 createBean 方法 然后返回 这个 bean, 执行 getSingleton 方法.
// 将 bean 加入到 singletonObjects 缓存起来 .还加入到了 registeredSingletons,
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// 如果报错了,要删除构建信息。
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 多实例的 bean 创建
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);
}
// 如果不是 singleton 或者 prototype 的,那么就是自定义的scope, 比如 session, global-session, 这里就交给自定义的scope的应用方法实现
// springmvc 中的 几个scope就是这么实现的.
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;
}
}
// Check if required type matches the type of the actual bean instance.
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;
}
我们来看看createBean(beanName, mbd, args)
11.1.4.7.1 createBean()
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 真正创建流程开始
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
// bean 的定义信息
RootBeanDefinition mbdToUse = mbd;
// 确保 BeanDefinition 中的 class 被加载,还记得我们之前看代码,有一个地方我们获取到了一个 ClassLoader ,我们不知道要这个ClassLoader干啥的,这里就是使用这个ClassLoader将用到的bean 的class文件装载到jvm
// 有一些动态加载的bean的定义信息也确保能够加载。看不懂没关系,跳过先
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 准备方法覆写,这里又涉及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />和 <replaced-method />
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 11.1.4.7.2 给 InstantiationAwareBeanPostProcessor 一个返回代理而不是目标 bean 实例的机会。
// 后面 aop 源码的时候再看.
// 这个方法我们下面列出来,她就是执行了 bean 初始化的 前置通知 和 后置通知。还记得我们之前注册过的 BeanPostProcessor 嘛?就是在这里执行的。
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 是代理对象 , 直接返回 bean
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 11.1.4.7.3 如果不是代理对象, 那么就调用这个
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
// 11.1.4.7.17 bean 初始化完成返回
return beanInstance;
} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
} catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
Object bean = resolveBeforeInstantiation(beanName, mbdToUse)
查看
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
看到applyBeanPostProcessorsBeforeInstantiation
和applyBeanPostProcessorsAfterInitialization
就知道了,她在bean的初始化前后分别回调了InstantiationAwareBeanPostProcessor
的实现类的postProcessBeforeInstantiation
和postProcessAfterInitialization
方法。
代理对象在这个之后就返回了。但是我们要看的不是代理对象,继续
11.1.4.7.3 Object beanInstance = doCreateBean(beanName, mbdToUse, args)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 11.1.4.7.4 创建实例 在这里 , 利用工厂方法 或者 无参构造函数, 创建 bean 的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 11.1.4.7.5 bean 实例化了之后 又调用了一个 BeanDefinitionPostProcessor
// 调用 实现了 MergedBeanDefinitionPostProcessor 接口的 postProcessMergedBeanDefinition 方法
// Spring 对这个接口有几个默认的实现, 比如我们常用的 @Autowired 注解
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
} catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 解决循环依赖问题
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 当正在创建 A 的时候, A 依赖 B, 但是 A 正在创建, 怎么给 B 呢? 这就是循环依赖
// 此处就是解决循环依赖的问题, 将 a 作为一个 ObjectFactory 提前对外曝光, 让其他人能够找到它,虽然他还没有完全初始化完毕.
// 那么 b 就可以在 cache中找到它, b 认为a已经创建了, 那么 b 就能够继续完成自己的初始化, 从而 a 也能够完成它的初始化.
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 11.1.4.7.6 为 Bean 实例属性赋值, 之前只是创建了bean,
// 主要是调用一些后置处理器[如果有定义的话], 然后利用反射调用set方法给 bean 的属性赋值.
// 这一步也是非常关键的,这一步负责属性装配,因为前面的实例只是实例化了,并没有设值,这里就是设值
populateBean(beanName, mbd, instanceWrapper);
// 11.1.4.7.11 这里就是处理 bean 初始化完成后的各种回调
// 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?
exposedObject = initializeBean(beanName, exposedObject, mbd);
} catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
} else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
// 11.1.4.7.16 注册 销毁 方法, 容器关闭时,调用销毁bean的方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
这里找出几个重点的
- instanceWrapper = createBeanInstance(beanName, mbd, args):这里实例化了bean
- applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName):执行一些回调
- populateBean(beanName, mbd, instanceWrapper):上面只是初始化bean,这里为bean属性赋值,包括内部用到的依赖
- exposedObject = initializeBean(beanName, exposedObject, mbd):bean 初始化完成后的各种回调
到这里终于看到了bean的实例化了。前面都是准备工作,包裹一些事件通知,前后回调。spring为我们开放了很多参与的入口。
先看 createBeanInstance 方法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 得到 class 为初始化准备
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 访问权限,跳过
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());
}
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
// 利用工厂方法实例化, 注意不是 FactoryBean
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
if (autowireNecessary) {
// 构造函数依赖注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 实例化bean 无参构造函数
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 无参构造器
return instantiateBean(beanName, mbd);
}
我们的重点是无参方法
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
} else {
// 实例化bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
// 包装一下实例化的 bean
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
} catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
我们看 getInstantiationStrategy().instantiate(mbd, beanName, parent)
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
// 看到 getDeclaredConstructor 是不是很熟悉,反射啊
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 到这里就是利用反射实例化bean了,
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 存在方法覆写,利用 CGLIB 来完成实例化,需要依赖于 CGLIB 生成子类,cglib先不讨论
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
以上我们不再深入,再下去就是反射的基本知识了
populateBean(beanName, mbd, instanceWrapper)
我们看属性赋值
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 {
// Skip property population phase for null instance.
return;
}
}
// 11.1.4.7.7 在赋值之前, 又一个 赋值的 后置处理器[如果有]. 看到 BeanPostProcessor 都已经麻木了吧。
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
// 11.1.4.7.8 得到属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// // 11.1.4.7.9 然后得到所有的后置处理器, 再去处理一下,[此时属性还没有赋值]
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 对采用 @Autowired、@Value 注解的依赖进行设值
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
// 11.1.4.7.10 最后才为属性赋值, 反射调用set方法
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
经过上面我们知道这个方法就是调用一些赋值前的回调,然后赋值。
initializeBean(beanName, exposedObject, mbd)
spring在我们实例化bean之后,还可以对bean做些初始化的工作。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 11.1.4.7.12 处理 Aware 接口的方法,
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 11.1.4.7.13 然后再次调用一个 BeanPostProcessor ,在 bean 初始化之前的操作.
// postProcessBeforeInitialization 方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 11.1.4.7.14 执行初始化方法.
// 是否实现了 InitializingBean 接口. 还记得我们写的测试 MyBean 嘛?
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// 11.1.4.7.15 又来了一个 BeanPostProcessor 在初始化之后调用的方法.
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
// 整个初始化完成
return wrappedBean;
}
这个方法不难理解,执行一些bean初始化操作。重点说下 Aware
Spring中提供了一些Aware接口,比如BeanFactoryAware,ApplicationContextAware,ResourceLoaderAware,ServletContextAware等,实现这些Aware接口的bean在被初始化后,可以取得一些相对应的资源,例如实现BeanFactoryAware的bean在初始化之后,Spring容器将会注入BeanFactory实例,而实现ApplicationContextAware的bean,在bean被初始化后,将会被注入ApplicationContext实例等
关于 invokeInitMethods(beanName, wrappedBean, mbd)
我们自定义的MyBean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑,打印。
init-method与afterPropertiesSet都是在初始化bean时执行,执行顺序是afterPropertiesSet先执行,而init-method后执行。
在invokeInitMethods方法中就实现了这两个步骤的初始化调用,详细的调用逻辑大家自己看源码了,就不列出占用篇幅。
12. finishRefresh()
这个方法完成收尾工作
protected void finishRefresh() {
// 去除缓存
clearResourceCaches();
// 12.1 初始化和生命周期有关的后置处理器
// 可以实现一个 LifecycleProcessor 接口, 在容器的生命周期关键点打印数据.
initLifecycleProcessor();
// 12.2 拿到了前面定义的生命周期(BeanFactory)处理器, 回调 onRefresh() 方法,记得这个方法不
getLifecycleProcessor().onRefresh();
// 12.3 发布容器刷新完成事件 ContextRefreshedEvent,
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
好了,到此为止BeanFactory已经完成了实例化并且初始化完毕。我们的ioc容器也就创建完成。
总结
附录
自定义标签的解析,顺带说明注解@Component的解析
在上面我们解析BeanDefinition的时候,在DefaultBeanDefinitionDocumentReader
中方法doRegisterBeanDefinitions
时,遇到了
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
// default节点: <import />、<alias />、<bean />、<beans />
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 {
// @Component,这个就是自定义标签对应的注解,
// @Service,@Controller,@Repository这些注解都被@Component注解所以,他们都是等价的,也都会被扫到
delegate.parseCustomElement(ele);
}
}
}
}
else {
// 非默认节点进入此方法
delegate.parseCustomElement(root);
}
}
我们重点看 delegate.parseCustomElement(ele);
自定义标签的解析,我们通过这个方法找到了下面的方法
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
// 通过xml的节点获取到对应的 命名空间URI【比如context的http://www.springframework.org/schema/context】
String namespaceUri = getNamespaceURI(ele);
if (namespaceUri == null) {
return null;
}
// 通过 命名空间 获取 NamespaceHandler, 先进入这个 resolve 方法
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// 开始解析自定义标签
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
很奇怪啊,这里的命名空间是什么呢?大家还记得xml配置文件中的配置吗?比如我们配置自动扫包的时候需要加一些网址,很多人不明白这个网址到底有啥意思,这里你就知道了。回顾一下定义
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">
我们先看resolve
方法
public NamespaceHandler resolve(String namespaceUri) {
// 获取所有一级配置的 handler,getHandlerMappings()这个方法获取到所有的命名空间和对应的uri的一个map
// 比如 <context:component-scan base-package="top.ybq87"/> 这个标签对应的
// uri是:http://www.springframework.org/schema/context
// getHandlerMappings()方法有个小坑,我们正常debug进入时发现handlerMappings已经被初始化了,但是我们没有找到任何地方调用它的,除了一个 toString()方法,所以就是因为这个toString的问题导致handlerMappings提前初始化。
// 具体参考: https://www.zhihu.com/question/61890921
Map<String, Object> handlerMappings = getHandlerMappings();
// 然后通过 uri 得到对应的 className :org.springframework.context.config.ContextNamespaceHandler
// 这个 handlerMappings 是什么时候初始化的呢
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
} else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
} else {
String className = (String) handlerOrClassName;
try {
// 既然我们得到了 className, 就能够通过反射加载这个类了
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 然后实例化对象
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 调用它的 init() 方法, 这个很重要。
namespaceHandler.init();
// 放入缓存
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
} catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
} catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
我们使用的是xml文件配置,得到的namespaceuri = org.springframework.context.config.ContextNamespaceHandler,那我们直接索索下这个类的定义, 然后看init()
方法
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}
发现这里只有一个init()方法,看到了很多熟悉的标签,我们查看component-scan
。会先创建一个 parser,然后注册进NamespaceHandlerSupport的parsers中。这个在之后的解析中用到,先记住这个。
退出resolve方法。handler.parse进入
public BeanDefinition parse(Element element, ParserContext parserContext) {
BeanDefinitionParser parser = findParserForElement(element, parserContext);
// 回调解析方法
return (parser != null ? parser.parse(element, parserContext) : null);
}
看到后面的执行解析,这就是回调了我们上面实例化的解析方法。我们查看parser.parse
的时候,发现一长串解析方法。选择
ComponentScanBeanDefinitionParser就会调用它的解析方法。
public BeanDefinition parse(Element element, ParserContext parserContext) {
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// Actually scan for bean definitions and register them.
// 定义一个扫描器,用来扫包
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 开始扫描, 然后将扫到的 bean 的定义信息 BeanDefinition 注入到 BeanFactory
// 扫包的时候 实际上,是把所有包下的class文件都扫描了的,并且利用asm技术读取java字节码并转化为MetadataReader中的AnnotationMetadataReadingVisitor结构
// 扫描器采用asm技术扫描java字节码文件,即.class文件。扫描时是扫描指定包下的全部class文件,转换成指定的MetadataReader结构后,再去判断是否符合扫描规则,符合的才加入候选bean中,并注册到容器中。
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
这个就不展开了,太多了,简单说下,这个方法就是得到了我们要扫描的包路径,然后迭代得到所有的file,然后去掉一些filter过滤的文件,封装为FileSystemResource,得到bean的定义信息,注册到 BeanFactory ,最后进行一些消息通知。
注解处理器会在bean实例化的时候被回调,因为他们都是 BeanPostProcessor 的子类。