Spring 三级缓存
Spring 三级缓存
createBean过程中,会去判断需要的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");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
在Spring程序中,定义以下类:
@Service("aService")
public class AService {
@Autowired
BService bService;
}
@Service("bService")
public class BService {
@Autowired
AService aService;
}
debug
在spring加载过程中,扫描到需要放入 ioc 容器的beanNames ,会去循环遍历这些 beanNames 然后将他们创造成一个个 Bean
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 是否是个 FactoryBean 这里进不来
}
else {
getBean(beanName);
}
}
}
以 AService 这个类 创建的过程为例:
getBean(beanName)-->doGetBean(...)-->getSingleton(beanName)--->getSingleton(beanName,false)
最终来到 getSingleton(String beanName, boolean allowEarlyReference) 这个方法
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// beanName = aService allEarlyReference=false
// Quick check for existing instance without full singleton lock
// 从一级缓存获取 bean 获取到直接返回
Object singletonObject = this.singletonObjects.get(beanName); // null
// isSingletonCurrentlyInCreation(beanName) true
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//第一次getSingleton 并不是在创建中,所以会直接返回空
// 不是在创建中,并且一级缓存还没有这个 aservice,那么就要 createBean
// 第一次不会走到这里,代码省略 .....
}
return singletonObject;
}
没有获取到,那 spring 就会创建一个,代码会来到这里 执行 createBean
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
进入到 DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory) 这个方法
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
synchronized (this.singletonObjects) {
// 从一级缓存获取,这时候肯定没有
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 + "'");
}
// 这个方法里面干了一件事:将这个bean放入正在创建的 这样一个set 集合里面
//this.singletonsCurrentlyInCreation.add(beanName)
beforeSingletonCreation(beanName);
// 接下来就是一系列判断
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 这个方法,传进来的是一个 lamda,会跳回,执行 lamda 里面的方法:
// return createBean(beanName, mbd, args); 这个方法里面调用的 doCreateBean
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;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
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) {
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;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.、
// 是否提前曝光
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
// 这时候 aService 就在创建当中,会放入 三级缓存 (第三级缓存)
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 到这里,aService 就已经实例化好了,接下来就是 填充属性了
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 会给 aService填充属性,由于aService里面依赖了bService,肯定是去获取,获取不到,再创建
//故再走一遍 getBean bService 的逻辑
// 最开始 bService 在一级缓存也没有,并且也不是在创建中直接返回了一个null,并且 bService也没有在创建中,所以我们要开始 ceateBean(bService) 并标记 bService 正在创建中,在doCreateBean中,将 bService 也加入了 三级缓存 这时候 三级缓存有 aService bService 创建完了之后,就该填充 bService 的属性了,由于 bService 又依赖了 aService,我们会去执行 getSingleton(aService)
populateBean(beanName, mbd, instanceWrapper);
// ceate bService 要去填充 aService 的属性,这时候已经在三级缓存找到了,就填好了
// 接下来就是 bService 的 生命周期剩下的事
// 初始化 bService,执行工厂回调方法、 init方法、和 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) { //true
// getSingleton 从一级缓存、二级缓存都没找到,传了个 false,直接返回null 了
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 进不来 省略了。。。。
}
// Register bean as disposable.
try {
// 注册 bService
// 判断是否是 propertype 以及 是不是在关闭时候需要销毁 这里 bService 并没有设置,
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
我们又来到了 DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)这个方法里面
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
// 一级缓存还是没有,下一步
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// 由于之前已经标志 aService 正在创建中,所以能走到这里
// 从二级缓存获取
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 二级缓存也没有,并且是支持循环依赖的(默认就支持)
// 这里可能是 spring 为了方法复用,加了一些重复的代码,具体也不知道为什么 ,下面加锁的才是我们现在这个流程需要的代码
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
// 一级缓存 singletonObjects
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 二级缓存 earlySingletonObjects
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 三级缓存 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 从三级缓存里面肯定会获取到,之前已经把 aService 加入了三级缓存嘛
singletonObject = singletonFactory.getObject(); // 执行 lamda,AOP
// 这里调用singletonFactory.getObject() 会去执行 当初加入时候那个 lamda 表达式里面的代码:getEarlyBeanReference(beanName, mbd, bean)
// 放入二级缓存,并把它从三级缓存删掉
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName); // 防止重复创建 aop 代理对象
}
}
}
}
}
}
return singletonObject;
}
Object sharedInstance = getSingleton(beanName); // 第一次 getSingleton 的时候返回空
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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}

浙公网安备 33010602011771号