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;
}
}
以上代码做的事情大概是:
- 检查缓存中是否已经加载过
- 若没有加载,则记录beanName的正在加载状态,在 beforeSingletonCreation 方法中记录
- 加载单例前记录加载状态。(对循环依赖进行检测)
- 通过调用参数传入的 ObjectFactory 的个体 Object 方法实例化bean
- 加载单例后的处理方法调用(移除缓存该 bean 加载状态的记录)
- 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
- 返回处理结果
@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);
}
}
这个方法主要做了这样几件事
- 根据谁的 class 属性或者根据 className 来解析 Class
- 对 override 属性进行标记或验证
- 应用初始化前的后置处理器,解析指定的 bean 是否存在初始化前的短路操作
- 创建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));
这段代码实现。
具体步骤如下:
- Spring 容器创建单例 “A” bean,首先根据无参构造器常见 bean,并暴露一个 “ObjectFactory” 用于返回一个提前暴露一个创建中的 bean,并将 “A” 标识符放到 “当前创建 bean 池”,然后进行 setter 注入 B。
- 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;
}
这个方法的大概思路是
- 如果是单例则需要首先清除缓存
- 实例化 bean,将BeanDefinition转换为BeanWrapper。
- MergedBeanDefinitionPostProcessors 的应用:bean合并后的处理,Autowired 注解正式通过此方法实现诸如类型的预解析
- 依赖处理
- 属性填充
- 循环依赖检查:单例可以解决,但是对于构造和多例只能抛出异常
- 注册DisposableBean:如果配置了 destroyMethod,这里需要注册以便在销毁的时候调用
- 完成创建并返回
创建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);
}
这个方法的大概意思是
- 如果在 RootBeanDefinition 中存在factoryMethodName属性,或者说在配置文件中配置了 factoryMethod 属性,那么Spring 会尝试使用 instantiateUsingFactoryMethod(beanName, mbd, args); 方法根据 RootBeanDefinition 中的配置生成 bean 的实例
- 解析构造函数并进行构造函数的实例化。因为一个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



