栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring源码分析(2) —— Bean的加载和初始化

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring源码分析(2) —— Bean的加载和初始化

Bean的加载

 

package com.zhao;
 
import com.zhao.Interface.PressService;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
 
 
public class SourceCodeLearning {
 
    public static void main(String[] args) {
 
        //从容器中获取名字为user的bean
        BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        PressService pressService = (PressService) bf.getBean("pressService");
 
        //调用bean的方法
        String price = pressService.say();
        System.out.println(price);
 
    }
}

 PressService pressService = (PressService) bf.getBean("pressService"); 这句代码做了bean的加载和初始化。跟进源码,得到

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {


	protected  T doGetBean(final String name, @Nullable final Class requiredType,
							  @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		// 1 提取对应的beanName
		final String beanName = transformedBeanName(name);
		Object bean;

		
		// 2 直接尝试从缓存或者 SingletonFactories 中的 ObjectFactory 中获取
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}

			// 3 返回对应的实例,有时候存在诸如BeanFactory 的情况并不是直接返回实例本身而是返回指定方法返回的实例
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {

			// 4 只有在单例情况下才会尝试解决循环依赖,原型模式情况下,如果存在
			// 4 A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A
			// 4 造成循环依赖,也就是下面的情况   isPrototypeCurrentlyInCreation(beanName)  为true
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			BeanFactory parentBeanFactory = getParentBeanFactory();

			// 5 如果 beanDefinitionMap 中也就是在所有已经加载的类中不包括 beanName 则尝试从
			// 5 parentBeanFactory 中检测
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				String nameToLookup = originalBeanName(name);

				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}

				// 递归到 BeanFactory 中寻找
				else if (args != null) {

					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {

					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			// 如果不是仅仅做类型检查则是创建 bean,这里要进行记录
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {

				// 6 将存储Xml配置文件的 GernericBeanDefinition 转换为 RootBeanDefinition,
				// 6 如果指定BeanName 是子 Bean 的话同时会合并父类的相关属性
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				String[] dependsOn = mbd.getDependsOn();

				// 7 若存在依赖则需要递归实例化依赖的bean
				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);
						}
					}
				}

				// 8.1 实例化依赖的 bean 后便可以实例化 mbd 本身了
				// 8.1 singleton 模式的创建
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {

                            // 8.2 创建bean
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {

							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {

					// 8 Prototype 模型的创建(new)
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					
					// 8 指定的 scope 上实例化 bean
					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;
			}
		}

		// 9 检查需要的类型是否符合 bean 的实际类型
		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.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

}
​​​​​​​1  提取对应的beanName
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {

	private final Map singletonObjects = new ConcurrentHashMap<>(256);

	
	private final Map> singletonFactories = new HashMap<>(16);

	
	private final Map earlySingletonObjects = new HashMap<>(16);

	
	private final Set registeredSingletons = new linkedHashSet<>(256);




	
	private final Map> containedBeanMap = new ConcurrentHashMap<>(16);

	
	private final Map> dependentBeanMap = new ConcurrentHashMap<>(64);

	
	private final Map> dependenciesForBeanMap = new ConcurrentHashMap<>(64);


	@Override
	@Nullable
	public Object getSingleton(String beanName) {

        // 参数 true 设置标识允许早期依赖
		return getSingleton(beanName, true);
	}


	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {

        // 检查缓存中是否存在实例
		Object singletonObject = this.singletonObjects.get(beanName);

		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {

            // 如果为空,则锁定全局变量并进行处理
			synchronized (this.singletonObjects) {

                // 如果此 bean 正在加载则不处理
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {

                    // 当某些方法需要提前初始化的时候则会调用 addSingletFactory 方法将对应的
                    // ObjectFactory 初始化策略存储在 singletonFactories
					ObjectFactory singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {

                        // 调用预先设定的 getObject() 方法
						singletonObject = singletonFactory.getObject();

                        // 记录在缓存中,earlySingletonObjects 和 singletonFactories 互斥
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}


}

讲解:这个方法首先尝试从 singletonObjects 里面获取实例,如果获取不到再从 earlySingletonObjects 里面获取,如果还是获取不到,再尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory ,然后调用这个 ObjectFactory 的 getObject 来创建bean,并放到 earlySingletonObjects 里面去,并且从 singletonObjects 里面 remove 掉这个 ObjectFactory ,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在 allowEarlyReference 为true的情况下才会使用。

简单解释两点:singletonFactories 集合中的值,类型是 ObjectFactory,这个类是用来创建bean的,可能有人不解,创建 bean 不是用反射去创建吗?为什么来了一个 ObjectFactory 创建,没错,无论什么bean最终都会通过反射来创建,但你需要在配置文件中配置你要创建的这个 bean 的各种信息。但 FactoryBean 就不同,你可以通过getObject()方法直接返回需要创建的bean。

第二点:singletonObjects 创建完 bean 后为什么要 remove 掉这个 ObjectFactory。因为这是创建单例bean,bean实例化放入 earlySingletonObjects 后,再次获取在缓存中就可以得到,就无需再保留这个 ObjectFactory 了。

这里设计用于存储 bean 的不同 map,简单解释一下:

singletonObjects :用于保存 BeanName 和创建 bean 实例之间的关系,bean name --> bean instance

singletonFactories : 用于保存 BeanName 和创建 bean 的工厂之间的关系,bean name --> ObjectFactory

earlySingletonObjects : 也是保存 BeanName 和创建 bean 实例之间的关系,与 singletonObjects 的不同之处在于,当一个单例 bean 被放到这里面后,那么当 bean 还在创建过程中,就可以通过 getBean 方法获取到了,其目的是用来检测循环引用。

 registeredSingletons : 用来保存当前所有已注册的 bean

3 返回对应的实例,返回getObject()实例或者返回FactoryBean实例
	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;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(transformedBeanName(name), 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.
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		Object object = null;
		if (mbd == null) {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			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());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

Spring在获取bean的规则有这样一条:尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor 的 postProcessAfterInitialization 方法进行处理。在实际开发过程中大可以针对此特性设计自己的业务逻辑。

8.1  singleton 模式的创建 (在第一次加载bean的时候,缓存中没有,所以要新创建)
	public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");

        // 全局变量需要同步
		synchronized (this.singletonObjects) {

            // 首先检查对应的bean是否已经加载过,
            // 因为 singleton 模式其实就是复用已创建的bean,这一步是必须的
			Object singletonObject = this.singletonObjects.get(beanName);

            // 如果为空才可以进行 singleton 的 bean 的初始化
			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 + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new linkedHashSet<>();
				}
				try {

                    // 初始化 bean
					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;
		}
	}

以上代码做的事情大概是:

  1. 检查缓存中是否已经加载过
  2. 若没有加载,则记录beanName的正在加载状态,在 beforeSingletonCreation 方法中记录
  3. 加载单例前记录加载状态。(对循环依赖进行检测)
  4. 通过调用参数传入的 ObjectFactory 的个体 Object 方法实例化bean
  5. 加载单例后的处理方法调用(移除缓存该 bean 加载状态的记录)
  6. 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
  7. 返回处理结果
 8.2 创建bean return createBean(beanName, mbd, args);
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		if (logger.isDebugEnabled()) {
			logger.debug("Creating instance of bean '" + beanName + "'");
		}
		RootBeanDefinition mbdToUse = mbd;

	
        // 锁定 class,根据设置的 class 属性或者根据 className 来解析 Class
		Class resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}


		try {

            // 验证及准备覆盖的方法
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
		

            // 给 BeanPostProcessors 一个机会来返回代理来替代真正的实例
			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 {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("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);
		}
	}

这个方法主要做了这样几件事

  1. 根据谁的 class 属性或者根据 className 来解析 Class
  2. 对 override 属性进行标记或验证
  3. 应用初始化前的后置处理器,解析指定的 bean 是否存在初始化前的短路操作
  4. 创建bean 

对于第二点简单解释下,在bean实例化的时候如果检测到存在 methodOverrides 属性,会动态的为当前bean生成代理并使用对应的拦截器为 bean 做增强处理

创建 bean 前的短路,是这一步 if (bean != null) {     return bean;     },如果对bean增强后,bean已经创建好了,就直接返回,不会再去创建了。保证单例

第三点的代码,Bean实例化前的后置处理器,增强bean的功能

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {

                    // 在实例化之前应用 Bean 后处理器
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {

                        // 实例化之后应用 Bean 后处理器
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); 这段代码是给子类一个修改 beanDefinition 的机会,在bean实例化前会调用后处理方法进行处理。

	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

实例化之后引用 bean 后处理器

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

循环依赖

 对象A中有属性对象B,对象B中有属性对象A。当创建对象A时先创建A中的属性对象B,去创建对象B,又得创建对象A。

对象 A 中有属性 B

package com.zhao.service;

public class A {

    private B b;

    public A(B b) {
        this.b = b;
    }
    
    public void sayHello() {
        System.out.println("hello");
    }
}

对象 B 中有属性 A 

package com.zhao.service;

public class B {

    private A a;

    public B(A a) {
        this.a = a;
    }

    public void sayHello() {
        System.out.println("hello");
    }
}

配置文件 

      

      

启动类 

package com.zhao;

import com.zhao.Interface.PressService;
import com.zhao.service.A;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;


public class SourceCodeLearning {
    public static void main(String[] args) {
        //从容器中获取名字为user的bean
        BeanFactory bf = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
        A a = (A) bf.getBean("a");
    }
}

控制台报错 

这种构造方法造成的循环依赖是无法解决的。只能通过报错表示循环依赖

Spring容器将每一个正在创建的bean标识符放在一个 “当前创建bean池” 中,bean 标识符在创建过程中将一直保持在这个池中,因此如果在创建bean过程中发现自己已经在 “当前创建bean池” 里时,将抛出  BeanCurrentlyInCreationException 异常表示循环依赖;而对于创建完毕的 bean 将从 “当前创建bean池” 中清除掉。

以上是构造方法的循环依赖

Spring 对于 setter 注入方式构成的循环依赖是可以解决的,但是只能解决单例作用域的 bean 循环依赖。它是通过暴露一个单例工厂方法,从而使其它 bean 能引用到该bean。

通过 

addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

这段代码实现。

具体步骤如下:

  1. Spring 容器创建单例 “A” bean,首先根据无参构造器常见 bean,并暴露一个 “ObjectFactory” 用于返回一个提前暴露一个创建中的 bean,并将 “A” 标识符放到 “当前创建 bean 池”,然后进行 setter 注入 B。
  2. Spring 容器创建单例 “B” bean,首先根据无参构造器常见 bean,并暴露一个 “ObjectFactory” 用于返回一个提前暴露一个创建中的 bean,并将 “B” 标识符放到 “当前创建 bean 池”,然后进行 setter 注入 A。

至此完成 setter 依赖注入,其中最大的作用就是 缓存

但是对于多例对象,Spring是无法完成依赖注入的。因为 prototype 对象,Spring 是不进行缓存的。因此无法提前暴露一个创建中的 bean.

 创建Bean

前面通过代理或者将bean增强后改变了 bean,那直接返回即可。就是那个短路操作,如果经Bean实例化前的后置处理器,已经创建出代理bean了,那么就返回。如若不然,就按常规的 bean创建,这是在。Object beanInstance = doCreateBean(beanName, mbdToUse, args); 方法中完成的

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			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 {

					// 应用 MergedBeanDefinitionPostProcessors
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}

			// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
			addSingletonFactory(beanName,
					// 对 bean 再一次依赖引用,主要应用 SmartInstantiationAware BeanPostProcessor
					// 其中我们熟知的 AOP 就是在这里将 advice 动态织入 bean 中,若没有则直接返回 bean,不做任何处理
					() -> getEarlyBeanReference(beanName, mbd, bean)
								);
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {

			// 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性,则会递归初始依赖 bean
			populateBean(beanName, mbd, instanceWrapper);

			// 调用除耍滑方法,比如 init method
			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);

			// earlySingletonReference 只有在检测到有循环依赖的情况下才会不为空
			if (earlySingletonReference != null) {

				// 如果 exposedObject 没有在初始化方法中被修改,也就是没有被增强
				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 {

			// 根据 scope 注册 bean
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

 这个方法的大概思路是

  1. 如果是单例则需要首先清除缓存
  2. 实例化 bean,将BeanDefinition转换为BeanWrapper。
  3. MergedBeanDefinitionPostProcessors 的应用:bean合并后的处理,Autowired 注解正式通过此方法实现诸如类型的预解析
  4. 依赖处理
  5. 属性填充
  6. 循环依赖检查:单例可以解决,但是对于构造和多例只能抛出异常
  7. 注册DisposableBean:如果配置了 destroyMethod,这里需要注册以便在销毁的时候调用
  8. 完成创建并返回

创建bean分为了很多步,我们先从 instanceWrapper = createBeanInstance(beanName, mbd, args); 方法分析

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {

		// 解析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)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		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);
			}
		}

		// 需要根据参数解析构造函数
		Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_ConSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {

			// 构造函数自动注入
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 使用默认构造函数构造
		return instantiateBean(beanName, mbd);
	}

这个方法的大概意思是

  1. 如果在 RootBeanDefinition 中存在factoryMethodName属性,或者说在配置文件中配置了 factoryMethod 属性,那么Spring 会尝试使用 instantiateUsingFactoryMethod(beanName, mbd, args); 方法根据 RootBeanDefinition 中的配置生成 bean 的实例
  2. 解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数集类型去判断最终会使用哪个构造函数进行实例化。但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制。如果已经解析过则不需要重复解析而是直接从 RootBeanDefinition 中属性 resolvedConstructorOrFactoryMethod 缓存的值去取,否则需要再次解析,并将解析的结果添加至  RootBeanDefinition 中的属性  resolvedConstructorOrFactoryMethod 中去。

实例化 bean 无非是有参构造的实例 或 无参构造的实例。这里只针对无参构造讲解,也就是 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((PrivilegedAction) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	} 



           

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号