全面开战系列之Spring源码---IOC启动流程(二)
全面开战系列之Spring源码---IOC实例化前的准备工作(三)
本篇主要分析bean实例化的大体过程,主要分为缓存,构造函数实例化bean,属性装配,回调生命周期接口这4个模块。对于各个模块的具体细节实现,在之后的章节会详细分析。本篇先把各个流程串起来,然后各个击破!
spring提供了FactoryBean接口实现自定义实例化bean功能。来看看FactoryBean接口
public interface FactoryBean
{
@Nullable
T getObject() throws Exception;@Nullable
Class> getObjectType();default boolean isSingleton() {
return true;
}}
重写getObject()方法即可自定义 生成bean。
如何获取由FactoryBean的getObject()方法生成的bean?
ApplicationContext.getBean(name); 其中这个 name 必须以 "&"开头,如 &student(之后看源码就知道)。
如何获取FactoryBean本身实现类?
ApplicationContext.getBean(name); 其中这个name 就是实现类的类名,无需特殊处理
接下来分析源码
在之前的文章,有分析到AbstractApplicationContext中的 refresh(),这个方法包含了IOC的整个启动过程。其中,有一个 finishBeanFactoryInitialization(),这个方法负责bean实例化过程。
AbstractApplicationContext.finishBeanFactoryInitialization()
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. //这种类型的bean最实用的场景就是用来将前端传过来的参数和后端的controller方法上的参数格式转换的时候使用 // 如 String 转 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)); } // 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. //利用EmbeddedValueResolver可以很方便的实现读取配置文件的属性:${} if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. //先初始化 LoadTimeWeaverAware 类型的 Bean 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. //冻结所有的bean定义,即已注册的bean定义将不会被修改或后处理 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. //初始化 beanFactory.preInstantiateSingletons(); }
关注最后一行代码,beanFactory.preInstantiateSingletons(); 即DefaultListableBeanFactory.preInstantiateSingletons()
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 ListbeanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans...,遍历BeanName,实例化 for (String beanName : beanNames) { // 该方法的merge是指如果bean类继承有父类,那么就将它所有的父类的bd融合成一个RootBeanDefinition返回 // 合并父 Bean 中的配置,主要是 中的 parent属性 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //非抽象类,单例,非懒加载 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) {//如果是factoryBean,则需要加& 才能使用getBean //在 beanName 前面加上“&” 符号 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean> factory = (FactoryBean>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction ) ((SmartFactoryBean>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { // 不是FactoryBean的直接使用此方法进行初始化 getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... // 如果bean实现了 SmartInitializingSingleton 接口的,那么在这里得到回调 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
在遍历 beanNames 中,先判断 beanName是否是 FactoryBean类型,如果是,则实例化,通过这个方法:getBean(FACTORY_BEAN_PREFIX + beanName); 容器会自动为beanName加上特殊前缀:&,由此可见,对于容器中的FactoryBean类型的bean定义,IOC容器默认返回 FactoryBean的 getObject()中的实例。
具体看一下AbstractBeanFactory.isFactoryBean() ,这个方法通过 beanName 获取对应的bean定义 class类型,判断class是否是FactoryBean.class
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException { //转化名称,如"&name" --> "name"。因为容器中的beanName不会以"&"开头 String beanName = transformedBeanName(name); //先从缓存中获取实例 Object beanInstance = getSingleton(beanName, false); if (beanInstance != null) { return (beanInstance instanceof FactoryBean); } // No singleton instance found -> check bean definition. //从父容器中获取bean定义 if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) { // No bean definition found in this factory -> delegate to parent. return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name); } //从当前容器中获取bean定义,定义中的class 与FactoryBean.class进行对比 return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName)); }protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) { Class> beanType = predictBeanType(beanName, mbd, FactoryBean.class); return (beanType != null && FactoryBean.class.isAssignableFrom(beanType)); }
接下来具体看一下如何实例化bean的,即AbstractBeanFactory.getBean()方法
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}protectedT doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { /* * 通过 name 获取 beanName。这里不使用 name 直接作为 beanName 有两点原因: * 1. name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 本身,而非 FactoryBean * 实现类所创建的 bean。在 BeanFactory 中,FactoryBean 的实现类和其他的 bean 存储 * 方式是一致的,即 ,beanName 中是没有 & 这个字符的。所以我们需要 * 将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 实例。 * 2. 若 name 是一个别名,则应将别名转换为具体的实例名,也就是 beanName。 */ // 获取beanName,处理两种情况,一个是前面说的 FactoryBean(前面带 ‘&’),再一个这个方法是可以根据别名来获取Bean的,所以在这里是要转换成最正统的BeanName //主要逻辑就是如果是FactoryBean就把&去掉,如果是别名就把根据别名获取真实名称 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 检查是否已初始化,从缓存中获取实例 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { //如果已经初始化过了,且没有传args参数就代表是get,直接取出返回 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 + "'"); } } /* * 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果 * sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的 * bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回 * 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。 */ // 这里如果是普通Bean 的话,直接返回,如果是 FactoryBean 的话,返回它创建的那个实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } /* * 如果上面的条件不满足,则表明 sharedInstance 可能为空,此时 beanName 对应的 bean * 实例可能还未创建。这里还存在另一种可能,如果当前容器有父容器,beanName 对应的 bean 实例 * 可能是在父容器中被创建了,所以在创建实例前,需要先去父容器里检查一下。 */ else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // 如果存在prototype类型的这个bean, Spring无法处理循环依赖对象是prototype类型的问题。 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. //先从父容器取bean,如果不存在则创建。这里实现springMvc和spring容器交互 //springMvc容器可以访问父容器,Spring容器不能访问子容器 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // 如果当前BeanDefinition不存在这个bean且具有父BeanFactory // 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); } } //将beanName标记到baen工厂的alreadyCreated的Set中,保证不会重复创建该bean if (!typeCheckOnly) { markBeanAsCreated(beanName); } //准备创建bean try { // 合并父 BeanDefinition 与子 BeanDefinition final 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) { /* * 检测是否存在 depends-on 循环依赖,若存在则抛异常。比如 A 依赖 B, * B 又依赖 A,他们的配置如下: * * * * beanA 要求 beanB 在其之前被创建,但 beanB 又要求 beanA 先于它 * 创建。这个时候形成了循环,对于 depends-on 循环,Spring 会直接 * 抛出异常 */ 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.,单例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { //执行创建 Bean,但没有设置属性,创建 bean 实例,createBean 返回的 bean 是完全实例化好的 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 是 FactoryBean 类型,则调用工厂方法获取真正的 bean 实例。否则直接返回 bean 实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } // 如果是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); } // 如果不是 singleton 和 prototype 那么就是自定义的scope、例如Web项目中的session等类型,这里就交给自定义scope的应用方去实现 else { String scopeName = mbd.getScope(); final 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; } } //检查bean的类型 // 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; }
doGetBean()方法很长这里面是具体实例化过程,
主要分为以下步骤:
1. 从缓存中获取bean,如果有直接返回,没有则开始实例化,缓存逻辑主要在 getSingleton(beanName)这里面
2. 做一些校验,整合。如 对于prototype(多例)类型的bean无法实现循环依赖,整合父容器中的bean等
3.先实例化depends-on 类型的bean,如
4.实例化各种作用域的bean
实例化结束后,对于FactoryBean接口来说,需要关注 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); 此时,sharedInstance 已经是具体的实例了
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } //以&开头的beanName,表明beanInstance一定是想要 FactoryBean类型,否则抛异常 if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass()); } } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. //获取FactoryBean本身,如: applicationContext.getBean("factory"),name不以&开头表明想要获取该类本身,否则获取该类的getObject方法返回的bean if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } //调用 FactoryBean 接口的 getObject方法创建bean ,然后返回 Object object = null; if (mbd == null) { /* * 如果 mbd 为空,则从缓存中加载 bean。FactoryBean 生成的单例 bean 会被缓存 * 在 factoryBeanObjectCache 集合中,不用每次都创建 */ object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. // 经过前面的判断,到这里可以保证 beanInstance 是 FactoryBean 类型的,所以可以进行类型转换 FactoryBean> factory = (FactoryBean>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); //创建 bean object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
在getObjectForBeanInstance中,主要逻辑为:判断beanName是否意&开头,如果不是,则直接返回beanInstance,如果是,则最终调用FactoryBeanRegistrySupport.getObjectFromFactoryBean(factory, beanName, !synthetic)来创建bean。即最终调用 FactoryBean.getObject(); 方法创建自定义bean 然后返回。
protected Object getObjectFromFactoryBean(FactoryBean> factory, String beanName, boolean shouldPostProcess) { /* * FactoryBean 也有单例和非单例之分,针对不同类型的 FactoryBean,这里有两种处理方式: * 1. 单例 FactoryBean 生成的 bean 实例也认为是单例类型。需放入缓存中,供后续重复使用 * 2. 非单例 FactoryBean 生成的 bean 实例则不会被放入缓存中,每次都会创建新的实例 */ if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { //这里调用 FactoryBean.getObject() object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { // shouldPostProcess 等价于上一个方法中的 !synthetic,用于表示是否应用后置处理 if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } //加入singletonsCurrentlyInCreation 中(保存当前正在创建的类) beforeSingletonCreation(beanName); try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { //移除singletonsCurrentlyInCreation中的beanName afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) {//放入缓存 this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }private Object doGetObjectFromFactoryBean(final FactoryBean> factory, final String beanName) throws BeanCreationException { Object object; try { if (System.getSecurityManager() != null) { AccessControlContext acc = getAccessControlContext(); try { object = AccessController.doPrivileged((PrivilegedExceptionAction
在前面分析FactoryBean接口过程中,有提到实例化bean过程
doGetBean()方法具体实例化过程,
主要分为以下步骤:
1. 从缓存中获取bean,如果有直接返回,没有则开始实例化,缓存逻辑主要在 getSingleton(beanName)这里面
2. 做一些校验,整合。如 对于prototype(多例)类型的bean无法实现循环依赖,整合父容器中的bean等
3.先实例化depends-on 类型的bean,如
4.实例化各种作用域的bean
这里主要分析一下缓存,和 各作用域实例化过程。
在AbstractBeanFactory 类中的 doGetBean()方法,这个方法流程中有调用到DefaultSingletonBeanRegistry.getSingleton(beanName),这里面就是spring的缓存。
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从 singletonObjects 获取实例,singletonObjects 中缓存的实例都是完全实例化好的 bean,可以直接使用 Object singletonObject = this.singletonObjects.get(beanName); //检查当前bean是否正在被当前线程创建 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { /* * 如果 singletonObject = null,表明还没创建,或者还没完全创建好。 * 这里判断 beanName 对应的 bean 是否正在创建中 */ synchronized (this.singletonObjects) { // 从 earlySingletonObjects 中获取提前曝光的 bean,用于处理循环引用 singletonObject = this.earlySingletonObjects.get(beanName); // 如果如果 singletonObject = null,且允许提前曝光 bean 实例,则从相应的 ObjectFactory 获取一个原始的(raw)bean(尚未填充属性) if (singletonObject == null && allowEarlyReference) { // 获取相应的工厂类 ObjectFactory> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) {//表明 // 提前曝光 bean 实例,用于解决循环依赖 singletonObject = singletonFactory.getObject(); // 放入缓存中,如果还有其他 bean 依赖当前 bean,其他 bean 可以直接从 earlySingletonObjects 取结果 this.earlySingletonObjects.put(beanName, singletonObject); //放入earlySingletonObjects中,singletonFactories就可以清除,节约内存 this.singletonFactories.remove(beanName); } } } } return singletonObject; }
这里面的缓存结构涉及3个变量
/** Cache of singleton objects: bean name to bean instance. 完全初始化好的bean*/ private final MapsingletonObjects = new ConcurrentHashMap<>(256); /** Cache of singleton factories: bean name to ObjectFactory.用于存放 bean 工厂。bean 工厂所产生的 bean 是还未完成初始化的 bean。 */ private final Map > singletonFactories = new HashMap<>(16); /** Cache of early singleton objects: bean name to bean instance. 用于存放还在初始化中的 bean,用于解决循环依赖*/ private final Map earlySingletonObjects = new HashMap<>(16);
称为3级缓存,用于解决循环依赖问题。关于循环依赖,后续章节再详细分析,这里主要关注缓存获取流程即可。其实spring很多地方都有用到缓存,这样可以加快程序运行速度,以后写代码也可以仿造(get到小技巧)
bean的作用域分为: singleton,prototype,request,session,application,websocket.
这里只分析singleton(单例),即每个 Spring IoC 容器中只允许存在一个对象实例(同一个beanName)
关注AbstractBeanFactory的doCreateBean方法中一段代码
// Create bean instance.,单例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { //执行创建 Bean,createBean 返回的 bean 是完全实例化好的 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 是 FactoryBean 类型,则调用工厂方法获取真正的 bean 实例。否则直接返回 bean 实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
在 DefaultSingletonBeanRegistry.getSingleton()方法里面进行实例化操作,这里面的主要逻辑如下:
1. 调用传入的lambda方法。实际上就是调用createBean(beanName, mbd, args);
2.操作缓存
先来看一下DefaultSingletonBeanRegistry.getSingleton()整体流程
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { //如果当前正在创建的bean还处在另外线程的删除流程中。那就停止创建并抛出异常。 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加入到SetsingletonsCurrentlyInCreation中 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { // 调用传入的lambda方法。实际上就是调用createBean(beanName, mbd, args); 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; } // 将正在创建的bean从Set singletonsCurrentlyInCreation中移除 afterSingletonCreation(beanName); } if (newSingleton) { // 添加到bean工厂的singletonObjects中。加入缓存,此时bean的属性完整了 addSingleton(beanName, singletonObject); } } return singletonObject; } } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); //移除工厂 this.singletonFactories.remove(beanName); this.earlySingletonObjects.remove(beanName); this.registeredSingletons.add(beanName); } }
其中, addSingleton 和缓存有关,这里是解决循环依赖的关键
我们这节先重点分析 传入的 ObjectFactory 接口的 getObject 方法,即 AbstractAutowireCapableBeanFactory.createBean()。这个真正方法实现bean实例化操作
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. // 准备方法覆写,如果bean中定义了和 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 如果有代理(自定义bean)的话直接返回,处理InstantiationAwareBeanPostProcessor接口回调 // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) {//返回不为空,表明自定义bean实现成功,直接返回 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); } }
这里直接关注 Object beanInstance = doCreateBean(beanName, mbdToUse, args);这个方法,里面的大体逻辑为:
1.创建bean实例,主要通过 createBeanInstance(beanName, mbd, args) 这个方法
2.处理MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法
3.是否加入缓存
4.属性装配
5.各种接口,方法的回调,即网上常说的生命周期。
先看一眼 AbstractAutowireCapableBeanFactory.doCreateBean()方法的全貌
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 从缓存中获取 BeanWrapper,并清理相关记录 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; } // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { // 循环调用实现了MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法 // Spring对这个接口有几个默认的实现,其中大家最熟悉的一个是操作@Autowired注解的 //CommonAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor, ApplicationListenerDetector会被回调postProcessMergedBeanDefinition方法执行各自的逻辑。 // CommonAnnotationBeanPostProcessor处理@PostConstruct 和 @PreDestroy方法添加到org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#lifecycleMetadataCache CurrentHashMap中。 // 并且如果有就分别注册到bd的externallyManagedInitMethods和externallyManagedDestroyMethods Set集合中。 // org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition是再次进行bd的融合。 // 通过clazz.getDeclaredFields()得到bean中所有的属性字段和方法。然后挨个对其进行解析转换成metadata,最终放入到AutowiredAnnotationBeanPostProcessor#injectionMetadataCache中。 // ApplicationListenerDetector很简单,将beanName和是否是singleton的boolean变量放到ApplicationListenerDetector对象的MapsingletonNames中。 //解析注解上的属性,还未完成注入操作 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. /* * earlySingletonExposure 是一个重要的变量,这里要说明一下。该变量用于表示是否提前暴露 * 单例 bean,用于解决循环依赖。earlySingletonExposure 由三个条件综合而成,如下: * 条件1:mbd.isSingleton() - 表示 bean 是否是单例类型 * 条件2:allowCircularReferences - 是否允许循环依赖 * 条件3:isSingletonCurrentlyInCreation(beanName) - 当前 bean 是否处于创建的状态中 * * earlySingletonExposure = 条件1 && 条件2 && 条件3 * = 单例 && 是否允许循环依赖 && 是否存于创建状态中。 */ 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"); } //当正在创建A时,A依赖B,此时通过(将A作为ObjectFactory放入单例工厂中进行early expose,此处B需要引用A,但A正在创建,从单例工厂拿到ObjectFactory,从而允许循环依赖 // 获取早期 bean 的引用,如果 bean 中的方法被 AOP 切点所匹配到,此时 AOP 相关逻辑会介入 //在 getSingleton中会应用到ObjectFactory.getObject()获取早期bean引用,bean还没有完整的属性 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { //负责属性装配,很重要(依赖注入) populateBean(beanName, mbd, instanceWrapper); //这里是处理bean初始化完成后的各种回调,例如init-method、InitializingBean 接口、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 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 " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { // 把bean注册到相应的Scope中 registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
关注 instanceWrapper = createBeanInstance(beanName, mbd, args); 这里面根据配置生成bean,如 静态工厂方法,实例化工厂,构造函数
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // Make sure bean class is actually resolved at this point. //确保已经加载了class, 1.1 确保此时beanClassName已经加载,当然注解驱动时不会设置beanClassName属性 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()); } // 2. Supplier创建对象,Spring 新推出的 bean 创建方式。 Supplier> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } // 旧版本的Spring可以通过xml配置从而获得静态的工厂方法获得bean A //3. 工厂方法实例化,包括实例化工厂和静态工厂 if (mbd.getFactoryMethodName() != null) { // 采用工厂方法实例化 return instantiateUsingFactoryMethod(beanName, mbd, args); } // 缓存标志位 // RootBeanDefinition.resolvedConstructorOrFactoryMethod专门用来缓存构造函数, // constructorArgumentsResolved用来存放构造是有参还是无参。 // 有参走autowireConstructor,无参走instantiateBean // Shortcut when re-creating the same bean... boolean resolved = false; //是否采用有参构造函数注入 boolean autowireNecessary = false; if (args == null) { //4.1 args: 外部化参数,只能当无外部参数时才使用缓存。不推荐使用外部化参数,因为外部化参数会覆盖配置参数 bd.args 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? // 5.1 是否指定了构造器, Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // 指定注入模式为构造器自动注入模式, /* * 下面的条件分支条件用于判断使用什么方式构造 bean 实例,有两种方式可选 - 构造方法自动 * 注入和默认构造方法。判断的条件由4部分综合而成,如下: * * 条件1:ctors != null -> 后置处理器返回构造方法数组是否为空 * * 条件2:mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR * -> bean 配置中的 autowire 属性是否为 constructor * 条件3:mbd.hasConstructorArgumentValues() * -> constructorArgumentValues 是否存在元素,即 bean 配置文件中 * 是否配置了 * 条件4:!ObjectUtils.isEmpty(args) * -> args 数组是否存在元素,args 是由用户调用 * getBean(String name, Object... args) 传入的 * * 上面4个条件,只要有一个为 true,就会通过构造方法自动注入的方式构造 bean 实例 */ //@Bean也走这里 默认注入类型:AUTOWIRE_CONSTRUCTOR if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { //指定参数。包括配置参数 bd.constructorArgumentValues 或外部参数 args。 // 5.2 构造器实例化 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.,默认构造函数实例化bean,使用无参构造 return instantiateBean(beanName, mbd); }
对于通过构造函数进行实例化的bean,最终是通过反射方法生成bean。但是,由于一个bean可能存在多个构造函数,对于选择有参构造函数进行实例化的bean,spring需要判断选择合适的构造函数。
这里面的逻辑有些复杂,autowireConstructor(beanName, mbd, ctors, args),这个方法里面包含了spring选择构造函数的逻辑,有兴趣的自行深入了解吧。
在这直接分析无参构造函数实例化过程,AbstractAutowireCapableBeanFactory.instantiateBean(beanName, mbd);
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged((PrivilegedActionpublic Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. // 如果不存在方法覆写,那就使用 java 反射进行实例化,否则使用 CGLIB, 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>) clazz::getDeclaredConstructor); } else { //获取默认的构造函数 constructorToUse = clazz.getDeclaredConstructor(); } //设置到bd缓存上 bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } //执行实例化 return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. return instantiateWithMethodInjection(bd, beanName, owner); } }
在SimpleInstantiationStrategy.instantiate()方法最终会调用到 BeanUtils.instantiateClass(), 通过 Constructor.newInstance(args) 创建bean,对于无参构造函数创建的bean,此时bean的属性都为空,所以接下去需要进行属性装配(依赖注入)。
public staticT instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException { Assert.notNull(ctor, "Constructor must not be null"); try { ReflectionUtils.makeAccessible(ctor); return (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ? KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args)); } catch (InstantiationException ex) { throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex); } catch (IllegalAccessException ex) { throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex); } catch (IllegalArgumentException ex) { throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex); } catch (InvocationTargetException ex) { throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException()); } }
属性装配也可包含依赖注入
Spring的依赖注入 分为基于构造函数注入,基于setter方法注入,自动装配。
其中,自动装配方式又分为:no,byName,byType,constructor.
属性装配的源码在 AbstractAutowireCapableBeanFactory. populateBean()中,这里面的大体逻辑为:
1.处理 byName,byType类型的自动装配
2.处理InstantiationAwareBeanPostProcessor接口的回调方法,如 @Autowired、@Value 注解的属性进行设值
3.对属性进行赋值,如通过xml配置属性(通过set方法进行反射赋值)
具体看一下这个方法
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; // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { /* * 如果上面设置 continueWithPropertyPopulation = false,表明用户可能已经自己填充了 * bean 的属性,不需要 Spring 帮忙填充了。此时直接返回即可 */ 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); // Add property values based on autowire by name if applicable. // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系 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) { //这个变量主要用来保存非注解方式注入的属性,如XML配置,后面判断该变量是否为空, //然后对该变量进行反射注入操作 pvs = mbd.getPropertyValues(); } /* * 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理, * 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了, * 而是经过后置处理器修改后的内容 */ for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; //这里会对所有标记@Autowired、@Value 注解的属性进行设值 //如果还有其他方式的属性配置,如xml,会在后续继续进行复制操作。pvs传入什么,pvsToUser就输出什么 PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } 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) { //一个类如果只通过注解方式进行依赖注入,那么pvs的长度为0,在ibp.postProcessProperties // 已经完成了依赖注入 // 设置 bean 实例的属性值,主要是通过xml配置方式 applyPropertyValues(beanName, mbd, bw, pvs); } }
属性装配整体流程都在上面的方法中,这里不打算展开,因为要展开详细有点多,准备放在下一章单独分析,这里先了解流程。
bean到这里基本成型,属性也完整了,spring考虑到灵活性,扩展性,开发了一系列的接口供开发者使用。包括Aware, InitializingBean, BeanPostProcessor 接口,init-Method 方法
接下来看源码,AbstractAutowireCapableBeanFactory.initializeBean(beanName, exposedObject, mbd) 方法
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction
这篇文章主要是梳理了spring 实例化bean的流程,而并没有深入去分析各个细节模块。在下一章准备深入分析一下属性装配这一模块,一起期待吧!
写到这里,我只想说这篇文章是我写过的跨度最长时间文章。这篇文章至少在我的草稿箱里面呆了2个月。曾经几度想提起比来,但都未能如愿。原因嘛,主要是懒,当然还有其他原因。我也时常告诫自己,与其每天刷新闻,逛b站,不如把时间花在学习上面?思想惰性根深蒂固,习惯了舒适区的我已经成废人了。对此,我深感愧疚,同时对这种行为进行了严厉的自我谴责!还在最后幡然醒悟,痛改前非,赶在2021年前勉强完成,给2020画上了一个句号,惭愧惭愧。
最近有些丧,来句结语吧,大家不要受我影响~~
水纹珍簟思悠悠,千里佳期一夕休。
从此无心爱良夜,任他明月下西楼。