热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Spring源码分析之Bean生命周期

前言Spring中一个Bean的创建过程是十分复杂的,这里通过源码来简单分析一下。原理分析相关类图如下DefaultListableBeanFactory就是IOC容器的最终实现,

前言

Spring中一个Bean的创建过程是十分复杂的,这里通过源码来简单分析一下。


原理分析

相关类图如下

DefaultListableBeanFactory就是IOC容器的最终实现,既实现了BeanFactory接口,也实现了BeanDefinitionRegistry接口,

所以它不仅是Bean容器,也是BeanDefinition注册表,同时管理Bean和BeanDefinition,接下来就来分析一下DefaultListableBeanFactory是如何创建Bean的。

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
public class TestBeanFactory {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionBuilder definitiOnBuilder= BeanDefinitionBuilder
.genericBeanDefinition(UserService.class);
definitionBuilder.addPropertyValue("username", "lisi");
beanFactory.registerBeanDefinition("userService", definitionBuilder.getBeanDefinition());
UserService userService = (UserService) beanFactory.getBean("userService");
System.out.println(userService.getUsername());
}
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public static class UserService {
private String username;
}
}

我们先自己注册了UserService的BeanDefinition(项目中一般都是通过扫描自动注册的),核心方法就是beanFactory.getBean(beanName),接下来就深入到方法内部来看一下。

首先进入AbstractBeanFactory内部。

protected T doGetBean(final String name, @Nullable final Class requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//处理FactoryBean类型的Bean名称,暂时不管
final String beanName = transformedBeanName(name);
Object bean;
//查看是否已经创建过(从单例池中查询)
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
//也是处理FactoryBean相关
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
try {
//上面已经说了,DefaultListableBeanFactory也实现了BeanDefinitionRegistry,所以也管理BeanDefinition,这里根据Bean名称查询出之前注册的BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//处理依赖Bean,项目中一般也用不到
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
//依次创建依赖Bean
getBean(dep);
}
}
//创建单例Bean
if (mbd.isSingleton()) {
//创建完成之后会将Bean放到单例池中,下次直接从池中取就可以了
sharedInstance = getSingleton(beanName, () -> {
try {
//真正创建Bean的地方
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//销毁Bean
destroySingleton(beanName);
throw ex;
}
});
//处理FactoryBean相关
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//创建原型Bean(每次都会创建),暂时不管
else if (mbd.isPrototype()) {

}
else {
//处理其他scope的Bean,如web环境下的request类型的scope,暂时不管
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//检查Bean类型和我们要求的类型是否一致,进行类型转换
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T cOnvertedBean= getTypeConverter().convertIfNecessary(bean, requiredType);
return convertedBean;
}

}
return (T) bean;
}

除去非必要的代码,最终创建Bean的核心方法为createBean(),这个方法是通过AbstractAutowireCapableBeanFactory实现的,继续跟进去

@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
//解析出Bean的Class类型
Class resolvedClass = resolveBeanClass(mbd, beanName);

try {
//这里给BeanPostProcessors一个机会使用一个代理对象来代替目标Bean实例,关于BeanPostProcessor,下面介绍
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
try {
//实际创建Bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
}

继续doCreateBean()方法

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//创建Bean实例
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//也是处理FactoryBean相关
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建Bean实例,会找到最合适的构造器,通过反射创建对象
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
//允许BeanPostProcessor修改BeanDefinition,暂时不管
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
}
//解决循环依赖相关
boolean earlySingletOnExposure= (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
//初始化Bean实例
Object exposedObject = bean;
try {
//Bean属性装配,AutowiredAnnotationBeanPostProcessor就是在这里被调用来处理@Autowired和@Value注解的
populateBean(beanName, mbd, instanceWrapper);
//初始化Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
return exposedObject;
}

继续初始化Bean过程

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
//处理一些钩子方法的回调,如果当前Bean实现了BeanFactoryAware接口,就会调用当前Bean的setBeanFactory()方法
invokeAwareMethods(beanName, bean);
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessor的postProcessBeforeInitialization(),可以让我们在Bean初始化之前做一些事情,是Spring提供的一个扩展
//ApplicationContextAwareProcessor在这一步会处理更多的钩子方法的回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//调用我们定义的初始化方法,如果实现了InitializingBean接口,就调用afterPropertiesSet()方法,如果还配置了自定义初始化方法,也调用
//@Bean注解可以使用initMethod属性来配置
invokeInitMethods(beanName, wrappedBean, mbd);
}
if (mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessor的postProcessAfterInitialization(),可以让我们在Bean初始化之后做一些事情,也是Spring提供的一个扩展
//AOP创建代理对象就是通过AnnotationAwareAspectJAutoProxyCreator扩展此功能实现的
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

BeanFactory提供了addBeanPostProcessor()方法来添加我们自定义的BeanPostProcessor对象,如果使用ApplicationContext,就不需要手动添加了,我们只需要将它标记为一个Bean,ApplicationContext会自动去IOC容器中查找所有类型为BeanPostProcessor的Bean,调用addBeanPostProcessor()方法将它们添加到BeanFactory中。

@Component
public static class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
System.out.println("postProcessAfterInitialization: " + beanName);
return bean;
}
}

IOC容器底层是使用一个ConcurrentHashMap来保存Bean名称和Bean实例对象的对应关系的,DefaultListableBeanFactory是DefaultSingletonBeanRegistry的一个子类。


总结

Bean生命周期基本如下


参考

Spring IOC 容器源码分析



推荐阅读
author-avatar
TXCWB_523
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有