引言
概述: Spring Bean 创建源码分析系列
【1】Spring Bean 的实例化过程源码解析
【2】Spring 依赖注入(DI) 源码解析
【3】Spring 三级缓存解决循环依赖
1 工程介绍
1.1 StudentService
@Service
public class StudentService {
@Autowired
private TeacherService teacherService;
public StudentService(){
System.out.println("StudentService invoke NoArgsConstructor");
}
}
1.2 TeacherService
@Service
public class TeacherService {
@Autowired
private StudentService studentService;
public TeacherService(){
System.out.println("TeacherService invoke NoArgsConstructor");
}
}
1.3 applicationContext.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
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
default-lazy-init="false">
<context:component-scan base-package="com.rosh.service"/>
</beans>
1.4 RoshTest
public class RoshTest {
@Test
public void mainTest(){
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.close();
}
}
1.5 运行结果
2 三级缓存介绍
2.1 一级缓存
介绍: 当一个bean经过 创建实例、依赖注入、bean初始化,会存入一级缓存,我们说的单例池。
#创建实例
createBeanInstance(beanName, mbd, args)
#依赖注入
populateBean(beanName, mbd, instanceWrapper);
#bean的初始化
initializeBean(beanName, exposedObject, mbd);
描述: DefaultSingletonBeanRegistry getSingleton 方法。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
/**
* 【1】从一级缓存中获取,如果一级缓存中存在,则直接返回bean
*/
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
/**
* 【2】 把beanName添加到singletonsCurrentlyInCreation Set容器中,在这个集合里面的bean都是正在实例化的bean
*/
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
/**
*【3】 创建对象,调用AbstractAutowireCapableBeanFactory createBean
*
* 当调用singletonFactory.getObject();获取到对象时,说明对象已经完全创建成功
*
*/
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
}
catch (BeanCreationException ex) {
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
}
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
/**
* 【4】 创建成功后,真在创建的bean里面移除该bean
*/
afterSingletonCreation(beanName);
}
if (newSingleton) {
/**
* 【5】当对象完成创建时,把对象放入singletonObjects缓存中,bean完成创建时放入一级缓存
*/
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
描述: 当获取到创建的对象时,会将对象存入一级缓存(单例池),并且移除二级缓存、三级缓存。
2.2 三级缓存
描述: 存放仅完成创建实例的对象,该对象还没有进行依赖注入、初始化操作。AbstractAutowireCapableBeanFactory doCreateBean 方法:
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
/**
* 【1】创建实例
*/
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 {
/**
*【2】 收集有注解的属性、方法。
*
* 1 AutowiredAnnotationBeanPostProcessor 扫描 @Autowired、@Value注解
* 2 CommonAnnotationBeanPostProcessor 扫描 @PostConstruct、@Resource、@preDestroy
*/
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
/**
* bean是单例的、允许循环依赖、当前bean正在创建
*/
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");
}
/**
* 【3】 添加三级缓存,解决循环依赖
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
/**
* 【4】 依赖注入
*/
populateBean(beanName, mbd, instanceWrapper);
/**
* 【5】 初始化bean
*/
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;
}
2.3 二级缓存
描述: 解决循环依赖,提高获取效率,从三级缓存中获取对象,存入二级缓存,并且删除三级缓存里面的对象。AbstractBeanFactory doGetBean
DefaultSingletonBeanRegistry getSingleton 方法:
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//一级缓存中获取
Object singletonObject = this.singletonObjects.get(beanName);
//如果bean正在创建,还没创建完成
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//从二级缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
//二级缓存没有
if (singletonObject == null && allowEarlyReference) {
//从三级缓存中获取
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//获取到
if (singletonFactory != null) {
//从工厂中拿到对象
singletonObject = singletonFactory.getObject();
//升级到二级缓存
this.earlySingletonObjects.put(beanName, singletonObject);
//删除三级缓存
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
3 源码解析
3.1 过程概述
1 StudentService 完成创建、收集注解、存入三级缓存、依赖注入时,需要调用getBean("teacherService")
2 创建TeacherService 完成创建、收集注解、存入三级缓存、依赖注入时,会调用getBean("studentService")
3 AbstractBeanFactory 调用 doGetBean时:
(1) 调用方法Object sharedInstance = getSingleton(beanName);
(2) 会从三级缓存中获取获取studentService,存入二级缓存,并且删除三级缓存中studentService。
(3) 调用getObjectForBeanInstance(sharedInstance, name, beanName, null)方法获取bean,并且把bean返回给teacherService,完成teacherServcie的依赖注入。
(4) teacherSercice 执行initializeBean(beanName, exposedObject, mbd);
(5) 当teacherSercice 完成创建后,会加入单例池中,并且删除二级缓存、三级缓存信息。
(6) studentService完成依赖注入、初始化、存入一级缓存,删除二级缓存,三级缓存信息。
3.2 Debug
描述: studentService 完成实例化、注解收集、存入三级缓存池
描述: 依赖注入时会调用 getBean(“teacherService”)
描述: 直接在这里打打断点,由于循环依赖,当调用getBean(“teacherService”)时,teacherService会完成创建实例、收集注解、加入三级缓存,在进行依赖注入时,会调用getBean(“studentService”)
描述: 当执行getBean(“studentService”)会从三级缓存中获取到bean,并且把升级到二级缓存,删除三级缓存信息。
描述: 这样teacherService能获取到studentService,完成依赖注入,初始化。
描述: 获取到创建完成teacherService后,添加到单例池,并且删除二级、三级缓存池信息。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15093.html