1 说明
- 本文只是作为阅读spring源码梳理,没有太多源码贴进来;
- 梳理的只是个人认为比较重要的点
- 入口是机遇注解的spring容器,用的是 AnnotationConfigApplicationContext
2 使用
2.1 pom文件
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.9</version>
</dependency>
2.2 配置类
package spring.kewen.ding.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "spring.kewen.ding.bean")
public class DingConfig {
}
2.3 bean
package spring.kewen.ding.bean;
import org.springframework.stereotype.Component;
@Component
public class DingBean {
public String name = "dingkewen";
}
2.4 启动类与使用
package spring.kewen.ding;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import spring.kewen.ding.bean.DingBean;
import spring.kewen.ding.config.DingConfig;
public class Application {
public static void main(String[] args) {
AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(DingConfig.class);
DingBean dingBean = (DingBean)acac.getBean("dingBean");
System.out.println(dingBean.name);
}
}
3 源码入口
3.1 启动类构造函数说明
org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>…)
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
/*
// this()方法中的重点代码
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
1.this()
1.this()中看似只调用了两个方法,但是其实还有一个super(),super()中有各种受气的创建,比如:DefaultListableBeanFactory等
1.2. new AnnotatedBeanDefinitionReader(this) 除了创建reader,初始化registry等最重要的一点还有向beanDefs中设置各种spring自定义的各种PostProcessor
1.3. new ClassPathBeanDefinitionScanner(this)初始化扫描器
*/
this();
/*
2.register(componentClasses);//将自定定义的,并且传入到到启动容器中的配置类注册到BeanDefinition池中
最重要方法: this.beanDefinitionMap.put(beanName, beanDefinition);
*/
register(componentClasses);
/*
扫描所有文件,拿到因该被spring容器管理的类,注册到BeanDefinition池中,再从池中取出,创建spring中的bean对象,并缓存
下面进行重点解析
*/
refresh();
}
3.2 刷新方法说明(包含容器创建大部分功能,还有的功能在上面的构造方法中)
3.2.1 org.springframework.context.support.AbstractApplicationContext#refresh
重点关注方法:
- invokeBeanFactoryPostProcessors(beanFactory);//执行所有BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor
- registerBeanPostProcessors(beanFactory);// 将所有的 BeanPostProcessors 创建对象,放到单例池中;并且注册到beanfactory中(存在 private final List beanPostProcessors = new BeanPostProcessorCacheAwareList();)
- finishBeanFactoryInitialization(beanFactory);// 根据所有的beandefinition创建对象,放到单例池中
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
/*
1. 设置容器激活标志,并初始化一些变量比如监听器容器等
*/
// Prepare this context for refreshing.
prepareRefresh();
/*
2. 给spring容器设置序列化id,并返回容器(DefaultListableBeanFactory)
*/
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/*
向容器中添加postProsser
并且注册(是不是一部分,没有具体来找)前面放在BeanDefinition池中的benadefinition(直接跳过一级缓存,二级缓存,进入三级缓存),忽略一些接口
*/
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
/*
什么也没有做,只是一个空方法,留待子类扩展
*/
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
/*
说明:
1)先执行所有的 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
2)再执行 BeanFactoryPostProcessor#postProcessBeanFactory(这个先分成两大类,一种仅仅是BeanFactoryPostProcessor 还有一种是BeanDefinitionRegistryPostProcessor 因为BeanDefinitionRegistryPostProcessor implements BeanFactoryPostProcessor)
3)每个右分成三种,没有继承排序接口,继承Ordered,继承 PriorityOrdered,执行顺序是PriorityOrdered,Ordered到没有继排序接口的
4)防止重复执行,有一个 processedBeans 集合来保存beanName
执行顺序:
1)先执行传入的 BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
2)到BeanDefinations中找BeanDefinitionRegistryPostProcessor和PriorityOrdered,然后执行 postProcessBeanDefinitionRegistry
3)到BeanDefinations中找BeanDefinitionRegistryPostProcessor和Ordered,然后执行 postProcessBeanDefinitionRegistry
4)到BeanDefinations中找BeanDefinitionRegistryPostProcessor然后执行 postProcessBeanDefinitionRegistry
5)所有在容器中找都会判断不能在processedBeans出现并且每次找到了也要放到processedBeans中
5)然后执行BeanDefinitionRegistryPostProcessor#postProcessBeanFactory
6)到容器中拿BeanFactoryPostProcessor
7)循环,排除已经在processedBeans的,按照排序接口分类
8)然后执行BeanFactoryPostProcessor#postProcessBeanFactory
*/
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
/*
找到所有的BeanPostprocessors,
1)放到单例池中;
2)并且注册到beanfactory中(存在 private final List<BeanPostProcessor> beanPostProcessors = new BeanPostProcessorCacheAwareList();)
*/
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
/*
初始化国际化相关bean(name必须是messageSource),如果有就用自己的,如果没有就用默认的(DelegatingMessageSource)
*/
// Initialize message source for this context.
initMessageSource();
/*
初始化发布订阅模式中的发布者
*/
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
/*
什么也没做,留给子类扩展
*/
// Initialize other special beans in specific context subclasses.
onRefresh();
/*
初始化发布订阅模式中的订阅者
并尝试发布一次(如果有事件)
*/
// Check for listener beans and register them.
registerListeners();
/*
创建对象,比较重要,下面单独说
*/
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
contextRefresh.end();
}
}
}
3.2.2 ConfigurationClassPostProcessor特别说明
ConfigurationClassPostProcessor 是 BeanDefinitionRegistryPostProcessor的实现类之一,在 postProcessBeanDefinitionRegistry方法中对传入的文件夹进行扫描,根据class对象生成BeanDefinition (包括解析各种注解,比如import等)
1)执行链路(从ConfigurationClassPostProcessor开始,到拿到class文件):
postProcessBeanDefinitionRegistry:247, ConfigurationClassPostProcessor (org.springframework.context.annotation)
processConfigBeanDefinitions:331, ConfigurationClassPostProcessor (org.springframework.context.annotation)
parse:175, ConfigurationClassParser (org.springframework.context.annotation)
parse:207, ConfigurationClassParser (org.springframework.context.annotation)
processConfigurationClass:250, ConfigurationClassParser (org.springframework.context.annotation)
doProcessConfigurationClass:296, ConfigurationClassParser (org.springframework.context.annotation)
parse:132, ComponentScanAnnotationParser (org.springframework.context.annotation)
doScan:276, ClassPathBeanDefinitionScanner (org.springframework.context.annotation)
findCandidateComponents:315, ClassPathScanningCandidateComponentProvider (org.springframework.context.annotation)
scanCandidateComponents:429, ClassPathScanningCandidateComponentProvider (org.springframework.context.annotation)
2)简述过程
1.找到传入的配置文件,解析注解@ComponentScan 拿到传入的包名,
2.根据包名和classpath等,定位到文件夹,
3.找到文件下所有文件,封装成resource
4.根据resource和classlaod 通过asm框架,生成 MetadataReader (这里面有class,拿到了class,也就能拿到注解等了)
5.将MetadataReader根据条件(有没有某些注解等)转换成 BeanDefinition 缓存起来
3.3 对象创建说明(普通的没有引用的对象的创建)
说明:
- org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization(调用链路实在太长,就不一个一个贴代码了,只说重要的地方调用)
- 按照spring的bean的生命周期顺序来说明
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean(spring生命周期前半段创建对象~使用基本都逃不过这个方法)
下面按照生命周期以及调用生命周期的方法以及关键代码进行说明
- 构造方法
推导构造方法的方法:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance;
上面方法中,如果我们的bean没有构造方法,会调用 return ctor.newInstance(argsWithDefaultValues);最终一步步点下去(比较简单,就没有一步步写了)调用如下方法:
return ctor.newInstance(argsWithDefaultValues); - 执行MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法
实现类 | 功能 |
---|---|
CommonAnnotationBeanPostProcessor | 解析注解@PostConstruct,@PreDestroy和@Resource |
AutowiredAnnotationBeanPostProcessor | 解析注解@Autowrite和@Value |
ApplicationListenerDetector | 记录当前beanDefination是不是单例 |
简单说明解析@Resources注解和@Autowrite注解 |
- @Resource org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#buildResourceMetadata中会把复合的字段或方法组合成 ResourceElement 放到 List<InjectionMetadata.InjectedElement> elements中
- @Autowrite org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata中会把字段或方法组合成 AutowiredFieldElement 放到 List<InjectionMetadata.InjectedElement> elements 中
- 放入三级缓存
这个方法org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); - 根据InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation判断要不要继续往下执行
实现类 | 功能 |
---|---|
ConfigurationClassPostProcessor | 扫描文件转换成BeanDefinition,前面有说过了 |
AnnotationAwareAspectJAutoProxyCreator | aop创建代理,到aop中具体说明 |
CommonAnnotationBeanPostProcessor | @Resource 依赖注入,详情见下面 |
AutowiredAnnotationBeanPostProcessor | @Autowrite 依赖注入,详情见下面 |
依赖注入用到的最终方法是java.lang.reflect.Field#set
重点在于怎么拿到该设置的值
- 调用InstantiationAwareBeanPostProcessor#postProcessProperties给需要依赖注入的字段设置属性(还是上面的几个实现类),尤其是CommonAnnotationBeanPostProcessor,AutowiredAnnotationBeanPostProcessor
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- BeanPostProcessor#postProcessBeforeInitialization(@PostConstruct修饰的方法在InitDestroyAnnotationBeanPostProcessor中被调用,属于BeanPostProcessor)
- InitializingBean#afterPropertiesSet
- BeanPostProcessor#postProcessAfterInitialization
- 放入第一级缓存
- 销毁 先执行 加注解@PreDestroy的 DestructionAwareBeanPostProcessor#postProcessBeforeDestruction
- DisposableBean#destroy
3.4 CommonAnnotationBeanPostProcessor(@Resource拿依赖的调用链路)
/**
重要的功能是依赖注入 InstantiationAwareBeanPostProcessor#postProcessProperties
*/
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
/**
这里循环到 CommonAnnotationBeanPostProcessor
*/
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessProperties
/**
InjectionMetadata
*/
org.springframework.beans.factory.annotation.InjectionMetadata#inject
/**
AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement(CommonAnnotationBeanPostProcessor解析@Resource时创建的对象)
*/
org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject
/**
CommonAnnotationBeanPostProcessor.ResourceElement
*/
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.ResourceElement#getResourceToInject
/**
CommonAnnotationBeanPostProcessor
*/
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#getResource
/**
CommonAnnotationBeanPostProcessor
*/
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#autowireResource
/**
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeanByName
*/
resolveBeanByName:461, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
/**
AbstractBeanFactory
*/
org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class<T>)
3.5 AutowiredAnnotationBeanPostProcessor(@Autowired拿依赖的调用链路)
/**
重要的功能是依赖注入 InstantiationAwareBeanPostProcessor#postProcessProperties
*/
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
/**
这里循环到 AutowiredAnnotationBeanPostProcessor
*/
org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor#postProcessProperties
/**
InjectionMetadata
*/
org.springframework.beans.factory.annotation.InjectionMetadata#inject
/**
AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
(CommonAnnotationBeanPostProcessor解析@Autowrite时创建的对象)
*/
org.springframework.beans.factory.annotation.InjectionMetadata.InjectedElement#inject
/**
AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement
*/
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#resolveFieldValue
/**
DefaultListableBeanFactory
*/
org.springframework.beans.factory.config.AutowireCapableBeanFactory#resolveDependency(org.springframework.beans.factory.config.DependencyDescriptor, java.lang.String, java.util.Set<java.lang.String>, org.springframework.beans.TypeConverter)
/**
DefaultListableBeanFactory
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#doResolveDependency
/**
DependencyDescriptor
*/
org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate
/**
AbstractBeanFactory
*/
org.springframework.beans.factory.BeanFactory#getBean(java.lang.String)
4 三级缓存说明
4.1 哪三级缓存,存的分别是什么
- private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
第一级缓存,存放的是已经给变量赋值好的bean,拿出来就可以用的 - private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
第二级缓存,存放的虽然是我们取出时的对象,但是并没有进行依赖注入 - private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
第三级缓存,存放的是ObjectFactory
大概是这么放的 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));(可以自己定义创建对象的细节,比如动态代理也是从这个方法进入的)
4.2 每一级缓存是什么时候放的
情况一:没有循环依赖(没有用到第二级缓存)
1.创建对象
2.组装成ObjectFactory,放到第三级缓存
3.给对象设置属性等操作
4.从第三级缓存中取出对象(删除第三级缓存),放入第一级缓存
情况二:有循环依赖(A与B相互引用)
// A
public class A{
@Autowrite
private B b;
}
// B
public class B{
@Autowrite
private A a;
}
1.创建对象A
2.将对象A组装成ObjectFactory,放到第三级缓存
3.给A对象设置属性值(需要对象B,但是对象B暂时不存在,所以没有办法设置,要去创建B)
4.创建对象B
5.将对象B组装成ObjectFactory,放到第三级缓存
6.给B设置属性值,(需要对象A,但是对象A存在与第三级缓存中,以ObjectFactory形式存在)
7.从三级缓存中取出对象A(经过SmartInstantiationAwareBeanPostProcessor#getEarlyBeanReference处理),并存放到第二级缓存中
8.拿到第二级缓存中的A对象,给B对象设置属性值
9.B对象依赖注入结束,放到第一级缓存中
10.给A对象依赖注入结束,放到第一级缓存中
4.3 二级缓存足以解决循环依赖,为什么是三级缓存
1)首先第三级缓存中存放的是ObjectFactory,以便可以自己定制化创建对象,这种形式存在是必要的
2)如果存在代理,每次调用ObjectFactory.getObject()都会进行代理,生成一个新的代理对象
3)循环依赖中先创建的对象会有两次被取出,第一次是给后创建的对象赋值,第二次是移动到第一级缓存,这两次取出的对象要是同一个对象吧,但是从第三级缓存中取,每次取出的都是新建的代理对象。
4)总结,第二级缓存存在的含义既是存没有依赖注入完全的对象,也是暂存这个唯一的代理对象