共计 27930 个字符,预计需要花费 70 分钟才能阅读完成。
Spring 源码解析之八 finishBeanFactoryInitialization 办法即初始化单例 bean
七千字长文粗浅解读,Spirng 中是如何初始化单例 bean 的,和面试中最常问的 Spring 是如何解决循环依赖?
明天解读 Spring 外围办法 refresh() 中最最重要的一个办法 finishBeanFactoryInitialization() 办法,该办法负责初始化所有的单例 bean。
finishBeanFactoryInitialization() 办法位于 refresh() 中下标为 8 的地位。
到目前为止,应该说 BeanFactory 曾经创立实现,并且所有的实现了 BeanFactoryPostProcessor 接口的 Bean 都曾经初始化并且其中的 postProcessBeanFactory(factory) 办法曾经失去回调执行了。而且 Spring 曾经“手动”注册了一些非凡的 Bean,如 environment
、systemProperties
等。
剩下的就是初始化 singleton beans 了,大都数咱们的业务中都是单例 bean,就像咱们写的 @Controller、@Service 的类(没有设置懒加载的)都是在这个中央初始化,以供咱们应用,如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。
咱们先看一下 refresh() 的源码,大略看下 finishBeanFactoryInitialization(beanFactory) 所处的地位。
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//1、刷新前的筹备
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//2、将会初始化 BeanFactory、加载 Bean、注册 Bean
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//3、设置 BeanFactory 的类加载器,增加几个 BeanPostProcessor,手动注册几个非凡的 bean
prepareBeanFactory(beanFactory);
try {
//4、模板办法
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 执行 BeanFactory 后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
// 5、Register bean processors that intercept bean creation.
// 注册 bean 后置处理器
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 国际化
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//6、模板办法 --springboot 实现了这个办法
onRefresh();
// Check for listener beans and register them.
//7、注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//8、实现 bean 工厂的初始化 ** 办法重要 **********************************************
finishBeanFactoryInitialization(beanFactory);
//9、Last step: publish corresponding event.
finishRefresh();}
咱们深刻 finishBeanFactoryInitialization(beanFactory) 中,外面的调用线路盘根错节,还望读者能够做好心理准备。
/**
* 负责单例 bean 的初始化
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 最先初始化名字为 conversionService 的类,conversionService 类 它用来将前端传过来的参数和后端的 controller 办法上的参数进行绑定的时候用
// 尤其是用于非根底类型的转换
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(// 初始化在 getBean() 办法中实现
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
// 先初始化 LoadTimeWeaverAware 类型的 Bean aop 相关注:大略有个印象,当前解析 aop 会和它串起来。String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
//freeze 的单词意思是解冻,这个时候曾经开始预初始化,bean 定义解析、加载、注册先进行
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 开始初始化
beanFactory.preInstantiateSingletons();}
该办法是判断 bean 的一系列是不是属于某个类型的 bean,如果是就调用 getBean() 办法,如果不是,就调用 beanFactory.preInstantiateSingletons() 进行初始化,咱们先把 getBean() 放一放,重点看一看 beanFactory.preInstantiateSingletons() 办法。
@Override
public void preInstantiateSingletons() throws BeansException {if (logger.isTraceEnabled()) {logger.trace("Pre-instantiating singletons in" + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// this.beanDefinitionNames 保留了所有的 beanNames
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
//// 上面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作
for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 非形象、非懒加载的 singletons。如果配置了 'abstract = true',那是不须要初始化的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 解决 FactoryBean(负责初始化工厂的 bean)if (isFactoryBean(beanName)) {
// FactoryBean 的话,在 beanName 后面加上‘&’符号
// 此处调用 getBean() 办法
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {FactoryBean<?> factory = (FactoryBean<?>) bean;
// 判断以后 FactoryBean 是否是 SmartFactoryBean 的实现
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);
}
}
}
else {// 对于一般的 Bean,只有调用 getBean(beanName) 这个办法就能够进行初始化了
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 到这里阐明所有的非懒加载的 singleton beans 曾经实现了初始化
// 如果咱们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里失去回调
// 如果你想在单例 bean 初始化后做一些事 那就实现该接口
for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {smartSingleton.afterSingletonsInstantiated();
}
}
}
}
preInstantiateSingletons() 办法的次要工作是进行初始化的,在初始化前同样是一系列判断,如,是否是懒加载的,是否是一个 factorybean(一个特地的 bean,负责工厂创立的 bean),最初调用 getBean() 办法。
其中有个插曲是否实现了 SmartInitializingSingleton 接口,将接口让你能够在 bean 初始化后做一些事,咱们写一个简略的实例测试一下。
其余中央读者看正文理解一下即可,咱们开始持续深刻 getBean() 办法。
getBean() 办法外部调用了 doGetBean() 咱们间接看 doGetBean 办法。
// 咱们在分析初始化 Bean 的过程,然而 getBean 办法咱们常常是用来从容器中获取 Bean 用的,留神切换思路,// 曾经初始化过了就从容器中间接返回,否则就先初始化再返回
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {// 获取一个“正统的”beanName,解决两种状况,一个是后面说的 FactoryBean( 后面带‘&’),// 一个是别名问题,因为这个办法是 getBean,获取 Bean 用的,你要是传一个别名进来,是齐全能够的
String beanName = transformedBeanName(name);
// 返回值
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 查看下是不是曾经创立过了
Object sharedInstance = getSingleton(beanName);
// 这里说下 args,尽管看上去一点不重要。后面咱们一路进来的时候都是 getBean(beanName),// 所以 args 传参其实是 null 的,然而如果 args 不为空的时候,那么意味着调用方不是心愿获取 Bean,而是创立 Bean
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 的话,间接返回 sharedInstance,// 如果是 FactoryBean 的话,返回它创立的那个实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 创立过了此 beanName 的 prototype 类型的 bean,那么抛异样,// 往往是因为陷入了循环援用 哦,原来之前的循环依赖都是在这抛的异样,再有问题就不是无头苍蝇了
if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
// 检查一下这个 BeanDefinition 在容器中是否存在 BeanDefinition 既是蕴含了 bean 的一系列信息
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 如果以后容器不存在这个 BeanDefinition,试试父容器中有没有
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);
}
}
if (!typeCheckOnly) {
// typeCheckOnly 为 false,将以后 beanName 放入一个 alreadyCreated 的 Set 汇合中。markBeanAsCreated(beanName);
}
/*
* 稍稍总结一下:* 到这里的话,要筹备创立 Bean 了,对于 singleton 的 Bean 来说,容器中还没创立过此 Bean;* 对于 prototype 的 Bean 来说,原本就是要创立一个新的 Bean。*/
try {RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
// 先初始化依赖的所有 Bean,这个很好了解。// 留神,这里的依赖指的是 depends-on 中定义的依赖
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);
}
}
}
// Create bean instance.
// 如果是 singleton scope 的,创立 singleton 的实例
if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {
try {
// 执行创立 Bean,详情持续深刻
// 第三个参数 args 数组代表创立实例须要的参数,不就是给构造方法用的参数,或者是工厂 Bean 的参数嘛,不过要留神,在咱们的初始化阶段,args 是 null。// 这回咱们要到一个新的类了 AbstractAutowireCapableBeanFactory,看类名,AutowireCapable?类名是不是也阐明了点问题了。// 次要是为了以下场景,采纳 @Autowired 注解注入属性值: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);
}
// 如果是 prototype scope 的,创立 prototype 的实例
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {beforePrototypeCreation(beanName);
// 执行创立 Bean
prototypeInstance = createBean(beanName, mbd, args);
}
finally {afterPrototypeCreation(beanName);
}
bean = 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);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope'" + scopeName + "'is not active for the current thread; consider" +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
// 最初,检查一下类型对不对,不对的话就抛异样,对的话就返回了
if (requiredType != null && !requiredType.isInstance(bean)) {
try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean'" + name + "'to required type'" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
具体的实例化过程在 createBean() 办法中,咱们持续深刻 createBean() 办法。
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean'" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
// 确保 BeanDefinition 中的 Class 被加载
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
// 筹备办法覆写,这里又波及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method />
// 和 <replaced-method />,如果读者感兴趣,回到 bean 解析的中央看看对这两个标签的解析。try {mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理,// 在《Spring AOP 源码剖析》那篇文章中有解释,这里先跳过
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) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
咱们持续往里看 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) {
// 阐明不是 FactoryBean,这里实例化 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;
}
}
// 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));
if (earlySingletonExposure) {if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean'" + beanName +
"'to allow for resolving potential circular references");
}
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 这一步也是十分要害的,这一步负责属性拆卸,因为后面的实例只是实例化了,并没有设值,这里就是设值 ***************
populateBean(beanName, mbd, instanceWrapper);
// 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口?// 这里就是解决 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;
}
到这里,咱们曾经剖析完了 doCreateBean 办法,总的来说,咱们曾经说完了整个初始化流程。
在实例化 bean 后有一个特地重要的知识点,也是面试中最常问的,Spring 怎么解决循环依赖问题?外围代码就在这个办法外面。
循环依赖其实就是循环援用,也就是两个或则两个以上的 bean 相互持有对方,最终造成闭环。比方 A 依赖于 B,B 依赖于 C,C 又依赖于 A。如下图:
doCreateBean 办法有三个外围流程。
(1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象
(2)populateBean:填充属性,这一步次要是多 bean 的依赖属性进行填充
(3)initializeBean:调用 spring xml 中的 init 办法。
从下面讲述的单例 bean 初始化步骤咱们能够晓得,循环依赖次要产生在第一、第二步。也就是结构器循环依赖和 field 循环依赖。
那么咱们要解决循环援用也应该从初始化过程着手,对于单例来说,在 Spring 容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在 Cache 中,Spring 为了解决单例的循环依赖问题,应用了三级缓存。
咱们看一下 getSingleton 办法。
该办法还依赖于三个 map,这三个 map 就是三级缓存。
/** Cache of singleton objects: bean name to bean instance. */
// 单例对象的 cache
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */
// 单例对象工厂的 cache
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
// 提前曝光的单例对象的 Cache
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName);
// 判断以后单例 bean 是否正在创立中,也就是没有初始化实现 ( 比方 A 的结构器依赖了 B 对象所以得先去创立 B 对象
// 或则在 A 的 populateBean 过程中依赖了 B 对象,得先去创立 B 对象,这时的 A 就是处于创立中的状态。if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {singletonObject = this.earlySingletonObjects.get(beanName);
// 是否容许从 singletonFactories 中通过 getObject 拿到对象
if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
剖析 getSingleton() 的整个过程,Spring 首先从一级缓存 singletonObjects 中获取。如果获取不到,并且对象正在创立中,就再从二级缓存 earlySingletonObjects 中获取。
如果还是获取不到且容许 singletonFactories 通过 getObject() 获取,就从三级缓存 singletonFactory.getObject()(三级缓存) 获取,如果获取到了则:
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
从 singletonFactories 中移除,并放入 earlySingletonObjects 中。其实也就是从三级缓存挪动到了二级缓存。
从下面三级缓存的剖析,咱们能够晓得,Spring 解决循环依赖的窍门就在于 singletonFactories 这个三级 cache。
里就是解决循环依赖的要害,这段代码产生在 createBeanInstance 之后,也就是说单例对象此时曾经被创立进去 (调用了结构器)。这个对象曾经被生产进去了,尽管还不完满(还没有进行初始化的第二步和第三步),然而曾经能被人认出来了(依据对象援用能定位到堆中的对象),所以 Spring 此时将这个对象提前曝光进去让大家意识,让大家应用。
这样做有什么益处呢?
让咱们来剖析一下“A 的某个 field 或者 setter 依赖了 B 的实例对象,同时 B 的某个 field 或者 setter 依赖了 A 的实例对象”这种循环依赖的状况。
A 首先实现了初始化的第一步,并且将本人提前曝光到 singletonFactories 中,此时进行初始化的第二步,发现自己依赖对象 B,此时就尝试去 get(B),发现 B 还没有被 create,所以走 create 流程,B 在初始化第一步的时候发现自己依赖了对象 A,于是尝试 get(A),尝试一级缓存 singletonObjects(必定没有,因为 A 还没初始化齐全),尝试二级缓存 earlySingletonObjects(也没有),尝试三级缓存 singletonFactories,因为 A 通过 ObjectFactory 将本人提前曝光了,所以 B 可能通过 ObjectFactory.getObject 拿到 A 对象 (尽管 A 还没有初始化齐全,然而总比没有好呀),B 拿到 A 对象后顺利完成了初始化阶段 1、2、3,齐全初始化之后将本人放入到一级缓存 singletonObjects 中。
此时返回 A 中,A 此时能拿到 B 的对象顺利完成本人的初始化阶段 2、3,最终 A 也实现了初始化,进去了一级缓存 singletonObjects 中,而且更加侥幸的是,因为 B 拿到了 A 的对象援用,所以 B 当初 hold 住的 A 对象实现了初始化。
晓得了这个原理时候,必定就晓得为啥 Spring 不能解决“A 的构造方法中依赖了 B 的实例对象,同时 B 的构造方法中依赖了 A 的实例对象”这类问题了!因为退出 singletonFactories 三级缓存的前提是执行了结构器,所以结构器的循环依赖没法解决。
接下来咱们挑 doCreateBean 中的三个细节进去说说。一个是创立 Bean 实例的 createBeanInstance 办法,一个是依赖注入的 populateBean 办法,还有就是回调办法 initializeBean。
这三个办法也是极其简单的,读者有趣味能够持续的深刻进去。
1、createBeanInstance 办法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 确保曾经加载了此 class
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) {
// 采纳工厂办法实例化,不相熟这个概念的读者请看附录,留神,不是 FactoryBean
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 如果不是第一次创立,比方第二次创立 prototype 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 办法是怎么做的。
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
// 实例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
// 包装一下,返回
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
咱们能够看到,要害的中央在于:beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
外面是具体是实例化过程,咱们进去看看。
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
// 如果不存在办法覆写,那就应用 java 反射进行实例化,否则应用 CGLIB,
// 办法覆写 请参见附录 "办法注入" 中对 lookup-method 和 replaced-method 的介绍
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 利用构造方法进行实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
// 存在办法覆写,利用 CGLIB 来实现实例化,须要依赖于 CGLIB 生成子类,这里就不开展了。// tips: 因为如果不应用 CGLIB 的话,存在 override 的状况 JDK 并没有提供相应的实例化反对
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
到这里,咱们就算实例化实现了。咱们开始说怎么进行属性注入。
2、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;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}
}
}
}
// bean 实例的所有属性都在这里了
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
// 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
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 (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
// 这里有个十分有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor
// 对采纳 @Autowired、@Value 注解的依赖进行设值,这里的内容也是十分丰盛的
pvsToUse = ibp.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) {
// 设置 bean 实例的属性值
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
属性注入实现后,这一步其实就是解决各种回调了,这块代码比较简单。
3、initializeBean 办法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessBeforeInitialization 回调
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 解决 bean 中定义的 init-method,// 或者如果 bean 实现了 InitializingBean 接口,调用 afterPropertiesSet() 办法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcessor 的 postProcessAfterInitialization 回调
//BeanPostProcessor 的两个回调都产生在这边,只不过两头解决了 init-method
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
自此,Spring 实例化单例非懒加载 bean 的过程也就实现了,这也是 Spirng 最最重要的办法了。在咱们的日常应用 Spring 中,定义好各个类,而后在下面加上,@Controller,@Service,Autowired 等注解,这些注解是怎么起作用的呢?
想必大部分同学都是知其然,不知其所以然,想必通过本文,读者心中能有一个分明的意识。