文章目录
在我之前的一篇文章中(本文末的参考一),我们大致了解了从容器加载和获取一个bean的主要步骤,但是我们暂且忽略了Spring具体创建bean实例的过程,所以本篇文章我们需要继续深入分析createBean()流程。
- Spring容器获取是否已经存在的Bean,如果没有,就创建Bean对象然后根据实例化策略对Bean进行实例化。
- 实例化完成后,如果该bean设置了一些属性的话,则利用set方法设置一些属性。
- 执行Aware接口方法
如果该Bean实现了BeanNameAware接口,则调用setBeanName()方法。
如果该Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader()方法。
如果该Bean实现了BeanFactoryAware接口,则调用setBeanFactory()方法。 - 如果该容器注册了BeanPostProcessor,则会调用postProcessBeforeInitialization()方法完成bean前置处理
- 如果该bean实现了InitializingBean接口,则调用afterPropertiesSet()方法。
- 如果该bean配置了init-method方法,则调用init-method指定的方法。
- 初始化完成后,如果该容器注册了BeanPostProcessor则会调用postProcessAfterInitialization()方法完成bean的后置处理。
- 对象完成初始化,开始方法调用。
- 在容器进行关闭之前,如果该bean实现了DisposableBean接口,则调用destory()方法。
- 在容器进行关闭之前,如果该bean配置了destory-method,则调用其指定的方法。
其创建过程图如下:
IOC容器创建Bean的过程(源码分析)
1. getBean方法
AbstractBeanFactory通过getBean向IoC容器获取被管理的Bean,其方法的源码如下:
//获取IoC容器中指定名称的Bean
public Object getBean(String name) throws BeansException {
//doGetBean才是真正向IoC容器获取被管理Bean的过程
return doGetBean(name, null, null, false);
}
//获取IoC容器中指定名称和类型的Bean
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
//doGetBean才是真正向IoC容器获取被管理Bean的过程
return doGetBean(name, requiredType, null, false);
}
//获取IoC容器中指定名称和参数的Bean
public Object getBean(String name, Object... args) throws BeansException {
//doGetBean才是真正向IoC容器获取被管理Bean的过程
return doGetBean(name, null, args, false);
}
//获取IoC容器中指定名称、类型和参数的Bean
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
//doGetBean才是真正向IoC容器获取被管理Bean的过程
return doGetBean(name, requiredType, args, false);
}
//真正实现向IoC容器获取Bean的功能,也是触发依赖注入功能的地方
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//根据指定的名称获取被管理Bean的名称,剥离指定名称中对容器的相关依赖
//如果指定的是别名,将别名转换为规范的Bean名称
String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
//先从缓存中取是否已经有被创建过的单态类型的Bean,对于单态模式的Bean整
//个IoC容器中只创建一次,不需要重复创建
Object sharedInstance = getSingleton(beanName);
//IoC容器创建单态模式Bean实例对象
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
//如果指定名称的Bean在容器中已有单态模式的Bean被创建,直接返回
//已经创建的Bean
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的实例对象,主要是完成FactoryBean的相关处理
//注意:BeanFactory是管理容器中Bean的工厂,而FactoryBean是
//创建创建对象的工厂Bean,两者之间有区别
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {//缓存没有正在创建的单态模式Bean
//缓存中已经有已经创建的原型模式Bean,但是由于循环引用的问题导致实
//例化对象失败
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//对IoC容器中是否存在指定名称的BeanDefinition进行检查,首先检查是否
//能在当前的BeanFactory中获取的所需要的Bean,如果不能则委托当前容器
//的父级容器去查找,如果还是找不到则沿着容器的继承体系向父级容器查找
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
//解析指定Bean名称的原始名称
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
//委派容器bean工厂根据指定名称,指定的类型和显式的参数查找
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);
}
}
//创建的Bean是否需要进行类型验证,一般不需要
if (!typeCheckOnly) {
//向容器标记指定的Bean已经被创建
markBeanAsCreated(beanName);
}
try {
//根据指定Bean名称获取其父级的Bean定义,主要解决Bean继承时子类
//合并父类公共属性问题
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean有依赖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 + "'");
}
//把被依赖Bean注册给当前依赖的Bean
registerDependentBean(dep, beanName);
try {
//递归调用getBean方法,获取当前Bean的依赖Bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
//创建单态模式Bean的实例对象
if (mbd.isSingleton()) {
//这里使用了一个匿名内部类,创建Bean实例对象,并且注册给所依赖的对象
sharedInstance = getSingleton(beanName, () -> {
try {
//创建一个指定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.
//显式地从容器单态模式Bean缓存中清除实例对象
destroySingleton(beanName);
throw ex;
}
});
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//IoC容器创建原型模式Bean实例对象
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
//原型模式(Prototype)是每次都会创建一个新的对象
Object prototypeInstance = null;
try {
//回调beforePrototypeCreation方法,默认的功能是注册当前创//建的原型对象
beforePrototypeCreation(beanName);
//创建指定Bean对象实例
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//回调afterPrototypeCreation方法,默认的功能告诉IoC容器指//定Bean的原型对象不再创建了
afterPrototypeCreation(beanName);
}
//获取给定Bean的实例对象
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//要创建的Bean既不是单态模式,也不是原型模式,则根据Bean定义资源中
//配置的生命周期范围,选择实例化Bean的合适方法,这种在Web应用程序中
//比较常用,如:request、session、application等生命周期
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);
//Bean定义资源中没有配置生命周期范围,则Bean定义不合法
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的实例对象
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.
//对创建的Bean实例对象进行类型检查
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
//转换成指定类型的bean
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;
}
通过上面对向IoC容器获取Bean方法的分析,我们可以看到在Spring中,如果Bean定义的单态模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象。如果Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象。除此之外,Bean定义还可以扩展为指定其生命周期范围。
上面的源码只是定义了根据Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成,我们继续分析AbstractAutowireCapableBeanFactory的createBean方法的源码,理解其创建Bean实例的具体实现过程。
2. 创建Bean对象
AbstractAutowireCapableBeanFactory类实现了ObejctFactory接口,创建容器指定的Bean对象,同时还要对创建的Bean实例对象进行初始化处理。下面的doCreateBean(),才是真正创建bean实例的方法。
doCreateBean()方法的处理流程稍微复杂点,简述一下:
1、如果是单例bean,尝试从未完成创建的包装Bean缓存(factoryBeanInstanceCache)中获取BeanWrapper(bean的包装类), 如果获取成功,还将会清除对应的缓存;
2、完成bean的实例化的方法,根据指定bean使用的策略创建bean的实例,如工厂方法、构造方法自动注入、简单初始化;
3、获取包装器里面刚创建好的bean实例;
4、应用合并后的BeanDefinition后置处理器:执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition();
5、是否允许提前暴露bean对象(即半成品对象);
6、如果允许提前暴露,将会调用addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)方法,将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中;
7、属性填充,对bean各个属性值进行注入,可能存在依赖于其它bean的属性,则会递归初始依赖的bean;
8、初始化Bean,如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等等;
9、如果允许早期暴露,需要进行循环依赖检查;
10、注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理;
11、完成bean的创建并返回;
//创建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.
// 1、第一步:根据bean定义信息和bean名称解析得到bean的Class类型
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
// 2、第二步:验证并准备为此 bean 定义的方法覆盖
// 对overrides属性进行标记和验证,在xml解析阶段,将lookup-method和replace-method两个标签属性,保存在MethodOverrides中
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.
// 3、第三步:给InstantiationAwareBeanPostProcessor后置处理器一个机会,返回代理对象用来替换目标bean实例
// 如果返回不为空就直接返回代理bean(AOP功能就是基于这里判断的)
// InstantiationAwareBeanPostProcessor: 前置增强方法:postProcessBeforeInstantiation 后置增强方法:postProcessAfterInitialization
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 如果bean不为空的话,则直接返回,不执行下面的doCreateBean创建bean实例操作
return bean;
}
} catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
// 4、第四步:真正创建bean的方法
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
// 5、第五步:返回创建好的bean实例
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);
}
}
//真正创建Bean的方法
// org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 实例化bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 1、如果是单例bean,尝试从未完成创建的包装Bean缓存(factoryBeanInstanceCache)中获取BeanWrapper(bean的包装类), 如果获取成功,还将清除这个缓存
// private final ConcurrentMap<String, BeanWrapper> factoryBeanInstanceCache = new ConcurrentHashMap<>():FactoryBean名称 ==> BeanWrapper
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
// 如果缓存中不存在的话,则调用createBeanInstance创建一个BeanWrapper(bean的包装类)
if (instanceWrapper == null) {
// 2、完成bean的实例化的方法,根据指定bean使用的策略创建bean的实例,如工厂方法、构造方法自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 3、获取包装器里面刚创建好的bean实例
Object bean = instanceWrapper.getWrappedInstance();
// 获取实例化对象的类型
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 允许后处理器修改合并的 bean 定义
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// 4、应用合并后的BeanDefinition后置处理器:执行MergedBeanDefinitionPostProcessor后置处理器增强方法postProcessMergedBeanDefinition()
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.
// 5、是否允许提前暴露bean对象(即半成品对象)
// earlySingletonExposure的值由三部分确定:单例bean && 允许循环依赖 && 当前bean正在创建中
// isSingletonCurrentlyInCreation(beanName)的作用:返回指定的单例 bean 当前是否正在创建中
// allowCircularReferences:是否允许循环依赖,默认为true
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
// 6、如果允许提前暴露,将会调用addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)方法,将生成bean的工厂ObjectFactory添加到三级缓存(singletonFactories)中
// addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory)是Spring解决循环依赖非常关键的代码
if (earlySingletonExposure) {
if (logger.isTraceEnabled()) {
logger.trace("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 为避免循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂,将生成bean的工厂添加到三级缓存(singletonFactories)中
// 第二个参数同样是一个ObjectFactory,是一个函数式接口,当执行ObjectFactory的getObject()方法的时候,实际上执行的是getEarlyBeanReference(beanName, mbd, bean)
// getEarlyBeanReference(beanName, mbd, bean)的作用: 获取早期访问指定 bean 的引用
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// 初始化bean实例
Object exposedObject = bean;
try {
// 7、属性填充,对bean各个属性值进行注入,可能存在依赖于其它bean的属性,则会递归初始依赖的bean
populateBean(beanName, mbd, instanceWrapper);
// 8、初始化Bean,如执行aware接口、执行init-method方法、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);
}
}
// 9、如果允许早期暴露,需要进行循环依赖检查
if (earlySingletonExposure) {
// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
// 能进入这里,说明Spring检测到发生了循环依赖
// exposedObject == bean:两者相等,说明bean在执行initializeBean()初始化的时候,没有被后置处理器增强,还是原来那个对象
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
// allowRawInjectionDespiteWrapping: 表示是否允许在循环引用的情况下注入原始 bean 实例,即使注入的 bean 最终被增强器增强包装过,默认是false
// hasDependentBean(beanName):是否存在其他bean依赖了当前bean
// 获取到依赖当前bean的所有bean的beanName
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
// 尝试移除bean实例,因为执行到这里,说明exposedObject != bean,也就是bean已经被后置处理器增强,不是原来的对象了,
// 他们依赖的是原来的对象,属于脏数据,所以需要移除掉
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
// 使用actualDependentBeans记录那些移除失败的dependentBean
actualDependentBeans.add(dependentBean);
}
}
// 如果存在移除失败的,则需要抛出异常,Spring不允许脏依赖的存在(通过allowRawInjectionDespiteWrapping设置)
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 {
// 10、注册DisposableBean的实现,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理
registerDisposableBeanIfNecessary(beanName, bean, mbd);
} catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
// 11、完成bean的创建并返回
return exposedObject;
}
通过对方法源码的分析,我们看到具体的依赖注入实现在以下两个方法中:
(1).createBeanInstance:生成Bean所包含的java对象实例。
(2).populateBean :对Bean属性的依赖注入进行处理。
下面继续分析这两个方法的代码实现。
3. Bean对象的实例化
在createBeanInstance方法中,根据指定的初始化策略,使用静态工厂、工厂方法或者容器的自动装配特性生成java实例对象,创建对象的源码如下:
//创建Bean的实例对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
// 1、解析bean的Class类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 如果bean的Class类型不为空、bean不是public修饰的、且bean不允许访问非公共构造函数和方法,那么Spring会抛异常
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、如果存在用于创建 bean 实例的回调,则从给定的Supplier接口获取一个bean实例
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 3、如果存在工厂方法的话,即设置了factory-method,则使用工厂方法进行实例化
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 标识构造函数和工厂方法是否已经被解析过
boolean resolved = false;
// 是否需要自动注入
boolean autowireNecessary = false;
// 实例化bean的参数为空
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// resolvedConstructorOrFactoryMethod其实是一个缓存,存放已经解析过的构造函数和工厂方法,防止重复解析
if (mbd.resolvedConstructorOrFactoryMethod != null) {
// 如果缓存不为空,则修改resolved为true,标记为已解析
resolved = true;
// 是否需要自动注入的值取决于mbd的constructorArgumentsResolved属性(将构造函数参数标记为已解析的包可见字段)
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 4、如果构造函数和工厂方法已经被解析过,直接使用前面介绍的缓存resolvedConstructorOrFactoryMethod里面解析好的,如果需要自动注入,
// 则执行构造函数自动注入,否则使用默认构造函数进行实例化
if (resolved) {
if (autowireNecessary) {
// 如果需要自动注入,则执行构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
} else {
// 如果不需要自动注入,则使用默认构造函数进行实例化
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 5、传入beanClass和beanName,通过SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法,确定用于给定 bean 的候选构造函数
// 因为一个类可以有多个构造方法,每个构造方法都有不同的参数,所以需要根据参数以及类型去判断最终调用哪一个构造方法并进行实例化
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 满足下面四个条件的其中一个,都会执行构造函数的自动注入:
// a.determineConstructorsFromBeanPostProcessors()方法返回的构造方法不为空;
// b.bean的注入类型为AUTOWIRE_CONSTRUCTOR;
// c.存在bean定义的构造函数参数值;
// d.用于构造函数或工厂方法调用的显式参数不为空;
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
// 执行构造函数的自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
// 6、如果存在用于默认构造的首选构造函数,则执行构造函数的自动注入
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
// 构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, null);
}
// 7、如果既不存在工厂方法,也不存在带有参数的构造方法,则使用默认的构造方法进行bean的实例化
return instantiateBean(beanName, mbd);
}
//使用默认的无参构造方法实例化Bean对象
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
//获取系统的安全管理接口,JDK标准的安全管理API
if (System.getSecurityManager() != null) {
//这里是一个匿名内置类,根据实例化策略创建实例对象
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return 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);
}
}
经过对上面的代码分析,我们可以看出,对使用工厂方法和自动装配特性的Bean的实例化相当比较清楚,调用相应的工厂方法或者参数匹配的构造方法即可完成实例化对象的工作,但是对于我们最常使用的默认无参构造方法就需要使用相应的初始化策略(JDK的反射机制或者CGLIB)来进行初始化了,在方法getInstantiationStrategy().instantiate中就具体实现类使用初始策略实例化对象。
4. 使用默认的无参构造方法实现Bean对象的实例化
在使用默认的无参构造方法创建Bean的实例化对象时,方法getInstantiationStrategy().instantiate调用了SimpleInstantiationStrategy类中的实例化Bean的方法,其源码如下:
//使用初始化策略实例化Bean对象
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
//如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
//获取对象的构造方法或工厂方法
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
//如果没有构造方法且没有工厂方法
if (constructorToUse == null) {
//使用JDK的反射机制,判断要实例化的Bean是否是接口
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
//这里是一个匿名内置类,使用反射机制获取Bean的构造方法
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);
}
}
}
//使用BeanUtils实例化,通过反射机制调用”构造方法.newInstance(arg)”来进行实例化
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
//使用CGLIB来实例化对象
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
通过上面的代码分析,我们看到了如果Bean有方法被覆盖了,则使用JDK的反射机制进行实例化,否则,使用CGLIB进行实例化。
instantiateWithMethodInjection方法调用SimpleInstantiationStrategy的子类CglibSubclassingInstantiationStrategy使用CGLIB来进行初始化,其源码如下:
//使用CGLIB进行Bean对象实例化
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
//创建扩展子类
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
//根据扩展子类生成实例对象
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
//根据构造函数生成实例对象
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
// 通过回调拦截器为了避免内存泄漏
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
/**
* Create an enhanced subclass of the bean class for the provided bean
* definition, using CGLIB.
*/
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
//CGLIB中的类
Enhancer enhancer = new Enhancer();
//将Bean本身作为其基类
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
if (this.owner instanceof ConfigurableBeanFactory) {
ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
}
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
enhancer.setCallbackTypes(CALLBACK_TYPES);
return enhancer.createClass();
}
}
CGLIB是一个常用的字节码生成器的类库,它提供了一系列API实现java字节码的生成和转换功能。我们在学习JDK的动态代理时都知道,JDK的动态代理只能针对接口,如果一个类没有实现任何接口,要对其进行动态代理只能使用CGLIB。
5. 依赖注入(属性填充)
通过populateBean方法对Bean属性的依赖注入,由于内容比较多,其spring源码解析过程我把它放到我的另一篇文章里讲述,如本文末的参考二所述。
6. 初始化Bean:initializeBean
initializeBean()主要完成如执行aware接口、执行init-method方法、BeanPostProcessor后置增强等工作。
简述initializeBean()方法处理过程:
1、执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware;
2、执行BeanPostProcessor后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装;
3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method;
4、执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装;
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 1、执行Aware方法,如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2、执行BeanPostProcessor后置处理器的前置处理方法:postProcessBeforeInitialization(),允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 3、执行初始化方法,包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method
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()) {
// 4、执行BeanPostProcessor后置处理器的后置处理方法:postProcessAfterInitialization(),允许对bean实例进行包装
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
执行Aware方法 - invokeAwareMethods()
如BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
// 实现Aware接口的bean在被初始化后,可以取得一些相对应的资源,如BeanFactory、ApplicationContext等,下面就是具体的赋值过程
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
// 1、如果bean实现了BeanNameAware接口,那么在bean内部可以获取到BeanName属性
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
// 2、如果bean实现了BeanClassLoaderAware接口,那么在bean内部可以获取到BeanClassLoader对象
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
// 3、如果bean实现了BeanFactoryAware接口,那么在bean内部可以获取到BeanFactory工厂对象
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
执行BeanPostProcessor后置处理器的前置处理方法 - applyBeanPostProcessorsBeforeInitialization()
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1、获取到当前工厂中注册的所有BeanPostProcessor后置处理器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 2、执行每一个BeanPostProcessor的前置增强方法:postProcessBeforeInitialization()
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
// 3、如果postProcessBeforeInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强
return result;
}
// 4、使用增强后的bean current,赋值给result,然后返回
result = current;
}
return result;
}
执行初始化方法 - invokeInitMethods()
包括InitializingBean的afterPropertiesSet()方法、自定义的初始化方法init-method
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
// 1、检查bean是否实现了InitializingBean接口,如果实现了,则需要执行InitializingBean接口的afterPropertiesSet()方法
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
// 2、调用InitializingBean接口的afterPropertiesSet()方法
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
} catch (PrivilegedActionException pae) {
throw pae.getException();
}
} else {
((InitializingBean) bean).afterPropertiesSet();
}
}
// 3、调用用户自定义的初始化方法,比如init-method等
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
// 执行用户自定义的初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
//调用自定义的实例初始化方法
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
//获取自定义的方法名
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
//根据方法名获得方法
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
//如果自定义方法支持接口调用,就提供接口方法
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> methodToInvoke.invoke(bean), getAccessControlContext());
}
catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
}
else {
try {
//运用Java反射执行自定义的方法
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
执行BeanPostProcessor后置处理器的后置处理方法 - applyBeanPostProcessorsAfterInitialization()
实质执行BeanPostProcessor的后置增强方法postProcessAfterInitialization(),完成对bean实例进行包装
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 1、获取到工厂中注册的所有BeanPostProcessor后置增强器
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 2、执行BeanPostProcessor的后置增强方法postProcessAfterInitialization()
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
// 3、如果postProcessAfterInitialization()返回为空,则直接返回,将不会执行后续的BeanPostProcessor后置处理器的增强
return result;
}
// 4、使用增强后的bean current,赋值给result,然后返回
result = current;
}
return result;
}
7. 注册DisposableBean,用于销毁处理
通过registerDisposableBeanIfNecessary()方法注册DisposableBean,在注销时执行来源于DestructionAwareBeanPostProcessors、实现的DisposableBean的destroy方法还有自己配置的destroy-method的处理。
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
// 如果bean的作用域不是prototype,且bean需要在关闭时进行销毁
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
// 如果bean的作用域是singleton,则会注册用于销毁的bean到disposableBeans缓存,执行给定bean的所有销毁工作
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
} else {
// 如果bean的作用域不是prototype、也不是singleton,而是其他作自定义用域的话,则注册一个回调,以在销毁作用域内的指定对象时执行
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
// 注册用于销毁的bean到disposableBeans缓存
synchronized (this.disposableBeans) {
// private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
this.disposableBeans.put(beanName, bean);
}
}
Spring创建IOC容器和Bean对象的完成过程:
结合我的另外两篇文章(文末的参考一和二),Spring创建IOC容器和Bean的完整过程图如下:
参考一:
Spring源码解析IOC
作者:Dom点滴
链接:https://blog.youkuaiyun.com/u013568683/article/details/128582854
参考二:
Spring源码解析DI(XML和注解完整版)
作者:Dom点滴
链接:https://blog.youkuaiyun.com/u013568683/article/details/128737526