本文从源码角度深入分析spring的实现原理和关键技术点,争取一篇文章让你对spring有整体而深刻的理解。
注:本文基于目前(2021-6)spring最新版本5.3.7
一、整体分析
我们知道spring主要特性是ioc和aop,而这两者中最重要的还是ioc,它提供了管理bean的容器,其他特性都是基于此容器的。那么要了解spring,主要是看看它是怎么构建ioc的。
首先介绍ioc中最重要的两个类BeanFactory
和ApplicationContext
。事实上,我们可以把这两个接口当成2个体系的代表:
BeanFactory体系:包括以BeanFactory为基类的一系列实现了此接口的全部类。此体系实现了bean容器从注册到创建的一系列功能,表示了对bean容器的封装。
ApplicationContxt 体系: 包括了以ApplicationContext为基础一系列子类。此体系实现了对spring上下文的封装,包括ioc,aop,资源环境等一系列功能的管理,代表的是整个spring对外功能。
这里你可能会问,ApplicationContext不也实现了BeanFactory了么,是的,但我们这里主要是从功能和概念说的,BeanFactory是bean容器的封装;而ApplicationContext是对spring上下文的封装,不只是bean容器,两者不是一个级别。
事实上,ApplicationContext实现bean容器的管理工作靠的是内部维护了一个beanFactory引用而不是继承,毕竟要继承的话就要实现BeanFactory的全部功能,ApplicationContext才没有那么傻呢,直接引用下多方便啊,这也说明了一个设计原则:组合优于继承。关于如何引用的下文会详说。
了解了BeanFactory和ApplicationContext的基本定位后,让我们看看两者所代表的类体系吧。
DefaultListableBeanFactory
类结构图
ApplicationContext子类关系简图
说明:第一张图是DefaultListableBeanFactory的关系类图,第2张是ApplicationContext体系的简要子类结构。部分主要接口和类的功能已用红字标记出来了,这也是下面分析的重点。
DefaultListableBeanFactory
可谓BeanFactory的目前唯一的顶流(BeanFactory体系的顶点),也是ApplicationContext的座上宾(前文说的ApplicationContext引用beanFactory就是指它)。它(或者它的父类)实现了bean容器的所有该有的方法。也就是说,如果你只想要一个bean容器,它也就够了。另外多说一句,本来它还有个子类XmlBeanFactory
,无奈现在已经废弃了。
AnnotationConfigApplicationContext
是AppliactionContext体系注解式的最佳代表,使用它可以构建整个spring上下文,使用spring的各种功能。目前xml的方式用的很少了,大家都是用注解+扫描的方式构建spring上下文。
二、从一个demo开始
了解了spring的主要功能及主要的类,下面就开始具体分析吧。
首先,我们从一个demo开始,看看spring是如何启动的。以往的分析大都基于xml bean配置,近来大家都很少用这种方式了,所以这次我们使用注解的方式,手动启动一个spring上下文。
说明:依赖和业务bean的代码放附录二了,这里直接上测试用例
public static void main(String[] args) {
// ①使用注解类的spring上下文,构建出spring上下文
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// ② 扫描bean所在的包或手动注册bean
// applicationContext.scan("com.wthfeng.springtest");
applicationContext.register(AccountServiceImpl.class);
applicationContext.register(BusinessServiceImpl.class);
// ③刷新spring上下文,真正开始spring上下文流程,初始化bean,设置监听器,国际化等。
applicationContext.refresh();
// 获取业务bean
BusinessService businessService = applicationContext.getBean(BusinessService.class);
// 执行业务方法
businessService.handle("hefeng");
}
执行主方法,控制台输出hi! hefeng
,spring已经成功运行了。接下来,就是源码分析阶段了。
三、ApplicationContext部分
其中标注①②③的地方是关键节点,下面依次进行说明
① 构建spring环境
AnnotationConfigApplicationContext继承自GenericApplicationContext(忘了的话可以看看上面类图,加深下印象),看看两个类的构造方法。
public AnnotationConfigApplicationContext() {
// 自spring5.3新加的度量标准,用于记录bean的启动开始结束时间,分析性能用的,这里忽略
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 重要,初始化了用于解析注解的阅读器,除此之外还添加了若干有用的bean。下面细说
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 初始化用于扫描包的扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public GenericApplicationContext() {
// DefaultListableBeanFactory还记得么,就是BeanFactory体系的集大成者,
// 在这里直接构建出了beanfactory,后续有关bean容器的操作都委托给它了。
this.beanFactory = new DefaultListableBeanFactory();
}
我们上文说的ApplicationContext体系拥有BeanFactory的引用就是指此,除此之外,还有一处很重要的地方,this.reader = new AnnotatedBeanDefinitionReader(this);
初始化了注解阅读器,怎么初始化的现在不用管,关键是它还注册了若干bean,这个很重要。
追踪AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)
发现实现是如下方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 重要,给注册表注册所有注解相关的post处理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
继续往下追,关键代码如下
// 注册ConfigurationClassPostProcessor,用于扫描包和解析导入注解,是十分重要的bean
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册AutowiredAnnotationBeanPostProcessor,看名字就看出来了,用于解析类似@Autowired自动装配注解
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册了CommonAnnotationBeanPostProcessor,用于解析jsr-250支持的常用注解,如@Resource等
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册了PersistenceAnnotationBeanPostProcessor,用于支持JPA
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注册了EventListenerMethodProcessor,用于支持事件监听
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 注册了DefaultEventListenerFactory,一个默认事件监听工厂
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
注册bean如下
bean 名称 | 实现类 | 说明 |
org.springframework.context.annotation.internalConfigurationAnnotationProcessor | ConfigurationClassPostProcessor | 用于处理扫描包及处理引用注解等,如解析@ComponentScan,@Import,十分重要 |
org.springframework.context.annotation.internalAutowiredAnnotationProcessor | AutowiredAnnotationBeanPostProcessor | 处理自动装配 |
org.springframework.context.annotation.internalCommonAnnotationProcessor | CommonAnnotationBeanPostProcessor | 处理一些常用的注解,如@Resource等 |
org.springframework.context.annotation.internalPersistenceAnnotationProcessor | PersistenceAnnotationBeanPostProcessor | jpa支持 |
org.springframework.context.event.internalEventListenerProcessor | EventListenerMethodProcessor | 事件监听相关 |
org.springframework.context.event.internalEventListenerFactory | DefaultEventListenerFactory | 事件监听相关 |
这些bean处理器执行时机会有下文说明,不过在此之前,需要先了解 BeanFactoryPostProcessor和BeanPostProcessor,它们是spring2个重要的回调机制。具体详情可见附录一,这里简单说下。
BeanFactoryPostProcessor
在bean已加载好但没初始化的时机回调,利用这个特性可以修改、添加bean定义等。
BeanPostProcessor
这bean初始化过程调用,利用这个回调机制,可以实现自动装配,aop等特性。
② 注册bean
注册bean和扫描包分别是委托①中初始化的reader
和scanner
完成的。这里先明确下注册bean和初始bean的区别。
在beanfactory中,会保存bean的定义信息,如这个bean是哪个类的实例化对象,bean是否单例的,初始方法和销毁方法等等,这些信息保存在 beanDefinitionMap
中。其中bean名称为key。
注册bean的实质即是或手动或自动扫描的方式往beanDefinitionMap
添加bean。注意这里只是将bean定义放进去了,还没有初始化。
跟下代码
// AnnotationConfigApplicationContext
public void register(Class<?>... componentClasses) {
// 做个标记,忽略
Assert.notEmpty(componentClasses, "At least one component class must be specified");
StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
.tag("classes", () -> Arrays.toString(componentClasses));
// 调用reader(即AnnotatedBeanDefinitionReader)完成注册
this.reader.register(componentClasses);
registerComponentClass.end();
}
// 中间调用环节,忽略
// 不过可以发现个规律,spring做某件事XXX,往往真正干这件事的方法叫 doXXX()
public void registerBean(Class<?> beanClass) {
doRegisterBean(beanClass, null, null, null, null);
}
// 开始注册
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 创建bean定义对象,下面几行是给对象设置属性
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 包装下bean定义
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 执行注册逻辑,
// 注意这个this.registry其实就是spring上下文,在AnnotationConfigApplicationContext的构造函数中初始化reader时传的是this。
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
继续跟到BeanDefinitionReaderUtils类里
//BeanDefinitionReaderUtils
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
String beanName = definitionHolder.getBeanName();
// 这里就调用registry开始注册了
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// bean别名的处理
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
后面会调用GenericApplicationContext的registerBeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// 到这里是不是想起点什么,没错,GenericApplicationContext持有的
// beanFactory引用正是DefaultListableBeanFactory的实例,
// 最终干活的还是DefaultListableBeanFactory(笑哭)
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
关于DefaultListableBeanFactory的注册逻辑这里就先不分析了,等到讲BeanFactory时再说。总之,现在可以理解为注册好的bean都存在beanFactory的beanDefinitionMap
map映射中了。
现在总结下,我们已经
- 构建出了
ApplicationContext
上下文,显式创建出了beanFactory,从此有关bean工厂的事通通委托给它干; - 初始化了reader和scanner,它们都和加载注册bean定义有关,一个显式注册bean,一个扫描bean。
- 注册了若干beanFactory和bean的post processor,它们都和注解相关,会在下面的相应时机调用。
接下来,开始分析spring最重要的方法——refresh()了
③ Refresh方法
refresh方法是spring最重要的一个方法了(好像哪个都这么说)。它负责完成spring上下文的创建或刷新,位于AbstractApplicationContext
中。
public void refresh() throws BeansException, IllegalStateException{
// 加锁,开始进行刷新
// 为啥叫refresh而不是start之类的呢?因为spring可以多次刷新它的上下文
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// 刷新前的准备,标记开始,记录开始刷新时间,初始化环境等
prepareRefresh();
//① 重要,这里构建BeanFactory,拿到BeanFactory的引用
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 做一些准备工作,预设了一些bean,如environment,systemProperties等
prepareBeanFactory(beanFactory);
try {
// 设置 banFactory的回调点,供子类扩展
// 子类可根据需要实现BeanFactoryPostProcessor的接口,spring会在bean初始化前回调,用于修改、添加、删除bean定义
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// ② 就是在这里执行执行BeanFactoryPostProcessor的
invokeBeanFactoryPostProcessors(beanFactory);
// ③注册bean的post回调,这又是一种回调,与BeanFactory的post回调类似,这是在bean初始化时调用的
// 下文会详说
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// 初始化国际化信息,与主流程无关,忽略
initMessageSource();
// 初始化事件通知器
// spring会在容器初始化各个阶段通知给注册了相关事件的观察者,观察者模式
initApplicationEventMulticaster();
// 供子类实现的扩展
// 如子类可以在这里初始化web容器以提供web服务等
// 这个在讲解spring boot的时候细说,如果有的话(🤣)
onRefresh();
// 注册事件监听器
registerListeners();
// 重要,实例化单例bean(标记懒加载的除外)
// ④ Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 最后一步,做一些善后工作
// 发布spring上下文刷新完成事件等
finishRefresh();
} catch (BeansException ex) {
// 忽略
throw ex;
} finally {
// 忽略
}
}
}
这个方法基本完成了spring上下文的准备工作。并留了一些扩展点给子类实现,这是典型的模板方法的应用。除构建了bean容器并完成初始化任务外,还初始化了环境,事件发布以及监听等其他操作。由此可见ApplicationContxt与BeanFactory定位之不同。
1. obtainFreshBeanFactory
这个方法在xml体系中是很重要的,含义是刷新beanfactory工厂,在xml为代表的spring上下文类(如ClassPathXmlApplicationContext
)中,在这里会重新创建beanFactory,将xml配置文件的bean重新读取并装配一遍。
而注解式spring上下文中,这里就不太重要的。因为在前面的流程,beanfactory也创建了,bean也通过扫描或注册的方式加载到beanDefinitionMap
了。基本上bean已加载完毕,就等初始化了。
先看看方法吧
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
果然是个抽象,留给子类实现的。
再放一下applicationContext的类体系图加深下印象
从类图也可以看出,AbstractApplicationContext大致有2种实现,一个是通用的(GenericApplicationContext),一个是可刷新的(AbstractRefreshableApplicationContext)。分别对应了xml和注解两种实现。
看看GeneticApplicationContext是怎么实现的
// GenericApplicationContext类
// 主要就做了下标记,因为beanFactory在上面已经创建了
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
//GenericApplicationContext
// 直接返回beanFactory
public final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
顺便看下AbstractRefreshableApplicationContext
是怎么实现的吧
// AbstractRefreshableApplicationContext
protected final void refreshBeanFactory() throws BeansException {
// 因支持多次刷新,所以每次刷新前先销毁上次的beanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 也是直接创建出来的,
// 实现为 return new DefaultListableBeanFactory(getInternalParentBeanFactory());
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 这里从xml配置文件里读取配置并加载
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
// AbstractRefreshableApplicationContext
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
总结:
这两个分支的具体实现不一样,但功能还是一样的,就是初始化了beanFactory。
2. invokeBeanFactoryPostProcessors
现在我们已经初始化了BeanFactory,并加载了bean定义。如何加载会在BeanFactory部分讲解,现在只需知道它是通过扫描项目所在包或者手动注册的方式已经加载到了。
这里开始执行实现了BeanFactoryPostProcessor接口的类,来完成一些对Bean定义修改的回调。
看代码
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//委托PostProcessorRegistrationDelegate执行beanfactory的回调
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 设置织入的bean post处理器,与aop有关,暂忽略
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
重点是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
这里需要介绍下BeanFactoryPostProcessor
,之前说过它是bean定义的回调,就是在加载完bean后根据这些回调类对bean定义做一些修整,其实它有2个接口,还有一个继承了BeanFactoryPostProcessor
,是BeanDefinitionRegistryPostProcessor
,主要是添加bean定义,如使用SPI机制扫描其他包拿到的bean定义(在spring boot中很实用)该方法都有调用
代码太长就不贴了,主要有2行代码比较主要
// 执行BeanDefinitionRegistryPostProcessor的回调
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
// 执行BeanFactoryPostProcessor的回调
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
看下BeanDefinitionRegistryPostProcessor的定义
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
// 实现类可以注册自己需要的bean。BeanDefinitionRegistry可直接传入DefaultListableBeanFactory
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
3. registerBeanPostProcessors
接下来注册了bean的回调,也是委托PostProcessorRegistrationDelegate执行的。这里就不深入了。
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
4. finishBeanFactoryInitialization(beanFactory)
这一步是相当重要,就是它完成了非懒加载单例bean的初始化。
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 初始化ConversionService这个bean,它负责数据的转化工作,如将Date类型转为时间戳等
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// 添加属性解析器
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 织入相关
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
beanFactory.freezeConfiguration();
// 终于到了重点,初始化单例bean。不过applicationContext仍然没干啥活,直接交给beanFactory干了
beanFactory.preInstantiateSingletons();
}
refresh算是终于分析完了。这里总结下
ApplicationContext是spring上下文的代表,负责完成ioc、aop,环境设置,资源管理等spring众多功能。而spring的重要核心ioc,ApplicationContext直接创建了beanFactory的最高实现类DefaultListableBeanFactory
,并交给它处理了。
refresh()是ApplicationContext重要的生成上下文的地方,这里用了模板方法的模式,一些需要扩展的地方都留给子类去实现。
四、BeanFactory部分
再放下BeanFactory的类图加深下印象
这张图简要说明了BeanFactory体系主要类在bean初始化时做的工作。具体来说,主要是AbstractBeanFactory
以及它的子类AbstractAutowireCapableBeanFactory
完成了大部分工作。
AbstractBeanFactory
负责规划初始bean(getBean)的整个流程,AbstractAutowireCapableBeanFactory
负责创建并初始化bean,其他细节分散到各个类中。这也算模板方式的灵活应用吧。
好了,继续上篇的分析吧
// DefaultListableBeanFactory
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 已经注册了bean名称集合,
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 遍历bean,初始化非懒加载bean
for (String beanName : beanNames) {
// 合并bean定义,有些有继承关系的bean,需要合并父类bean的属性字段等,目前不常用了
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 判断bean性质,然后初始化
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果是工厂bean
if (isFactoryBean(beanName)) {
// 获取bean时带上固定前缀
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
// 普通bean的话,直接获取
else {
getBean(beanName);
}
}
}
// 单例bean初始化完成后,回调SmartInitializingSingleton类型的bean
// 相当于另一种类型的回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
smartInitialize.end();
}
}
}
无论什么类型的bean,初始化bean都是getBean
方法,getBean名字是获取bean,但也负责创建bean的任务。
关于工厂bean,指的是使用工厂方法的模式生产bean,这类bean一般创建较为复杂,或者依赖第三方等,附录三有这方面介绍。
关于SmartInitializingSingleton,实现了该接口的bean会在bean初始化完成进行回调。算是InitializingBean
机制的一种补充。
getBean
方法是下面分析的重点,为避免代码接下来代码太多,我列了该方法的主要路径:
好了,从getBean开始
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
主要是doGetBean方法,是获取bean的概括性方法
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// bean的别名转换,规范化bean name
String beanName = transformedBeanName(name);
Object beanInstance;
// 查看是否有单例缓存,反正原型又不可能有缓存
// 注意这个方法,与三级缓存解决循环依赖有关
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 + "'");
}
}
// 得到缓存,封装下
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 缓存没有,创建bean
else {
// 原型类型禁止循环依赖,如果发现则报错
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// bean定义不在当前beanFactory,查看父beanfactory
// 父beanfactory依然调用了getBean方法。
BeanFactory parentBeanFactory = getParentBeanFactory();
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);
}
}
// 下面要创建bean了,这里将bean加入创建中名单alreadyCreated
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
.tag("beanName", name);
try {
if (requiredType != null) {
beanCreation.tag("beanType", requiredType::toString);
}
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//处理dependsOn,dependsOn是bean的一种属性,可以理解为一个依赖条件
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 创建单例bean
if (mbd.isSingleton()) {
// getSingleton,第二个参数是个lambda表达式
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// 封装bean
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 创建原型bean
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 既不是单例也不是原型,处理自定义作用域
else {
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
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);
}
});
beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new ScopeNotActiveException(beanName, scopeName, ex);
}
}
}
catch (BeansException ex) {
beanCreation.tag("exception", ex.getClass().toString());
beanCreation.tag("message", String.valueOf(ex.getMessage()));
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
finally {
beanCreation.end();
}
}
// 适配bean,判断bean类型,返回泛型bean
return adaptBeanInstance(name, beanInstance, requiredType);
}
该方法总体是获取bean的主体方法,先从单例缓存中获取,有的话封装返回,没有的话创建后封装返回。封装方法getObjectForBeanInstance
后续再看,直接看 createBean
单例模式还会执行 getSingleton( beanName, singletonFactory)方法,最终会执行createBean,这里一步到位了。
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 确保解析bean的class类
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 该beans实现实现InstantiationAwareBeanPostProcessor,
// 是BeanPostProcessor的一种,在bean实例化前后执行,
// 如果实例前返回了bean,则跳过实例化,直接返回
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 真正创建bean的地方
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
doCreateBean是创建bean的核心方法
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// bean的包装类
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 重要,创建bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
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 {
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");
}
// 创建bean实例后添加到bean工厂,以解决循环依赖问题
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 给bean设置属性
populateBean(beanName, mbd, instanceWrapper);
// 执行bean的初始化方法,如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 " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
主要关注3个方法createBeanInstance
、populateBean
和initializeBean
。
// 主要是根据反射生成bean实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
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) {
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 {
// 无参数,直接简单反射生成
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);
}
后面就是使用反射生成实体类,跟踪instantiateBean
,最终会使用InstantiationStrategy生成实例,实现类有2个CglibSubclassingInstantiationStrategy
和SimpleInstantiationStrategy
。一个是cglib生成,一个是简单用反射生成。不过cglib的方法目前还不支持(?确实)。
看看主要代码即可。
// 调用实例策略生成实例(AbstractAutowireCapableBeanFactory.instantiateBean方法)
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
// 反射生成实例(BeanUtils.instantiateClass)
return ctor.newInstance(argsWithDefaultValues);
回头看看populateBean
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;
}
}
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
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);
// bean按名称注入,解析依赖
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// bean按类型注入,解析依赖
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();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = bp.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) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
附录一
关于 BeanFactoryPostProcessor和BeanPostProcessor
BeanFactoryPostProcessor和BeanPostProcessor是spring重要的2个回调机制。
先说 BeanFactoryPostProcessor,
@FunctionalInterface
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
执行时机是获取了bean定义,但bean还没有初始化之前调用,也即在代码中的②处调用的。可以在此修改bean定义,如配置文件中占位符的替换就发生在这里。在spring boot中,解析@SpringApplication得益于此机制。
BeanPostProcessor的执行时机在bean初始化完成后调用,如下代码描述,作用是对bean做一些定制化,如aop增强等。
public interface BeanPostProcessor {
// 在bean执行init-moethod方法前调用
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
// 在bean完成init-method方法后调用,这里就是完成spring AOP的地方。
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
附录二
有关spring依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.7</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
业务bean
@Service
public class AccountServiceImpl implements AccountService {
@Override
public String getUser(String user) {
String result = "hi! " + user;
System.out.println(result);
return result;
}
}
@Service
public class BusinessServiceImpl implements BusinessService {
@Autowired
private AccountService accountService;
@Override
public String handle(String param) {
return accountService.getUser(param);
}
}