书接上文
文章目录
- 一.、前文回顾
- 二、 创建Bean之getBean方法
一.、前文回顾
在前面一部分中,我们分析了Spring底层是如何加载BeanDefinition以及是如何将BeanDefinition注册到容器中的。以及分析了部分非懒加载单例Bean的实例化的内容,包括合并beanDefinition等。
二、 创建Bean之getBean方法
getBean
方法是从字面意思是获取容器中的Bean对象,它有多个重载方法,如下:
//按照Bean的名称获取Bean@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}//按照Bean的名称以及类型获取bean@Overridepublic <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}//按照Bean的名称同时指定了参数,表示按照指定构造函数初始化bean,同时返回bean@Overridepublic Object getBean(String name, Object... args) throws BeansException {return doGetBean(name, null, args, false);}
我们可以看出底层其实调用了doGetBean
方法
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx// name有可能传入进来的是别名,那么beanName就是idString beanName = transformedBeanName(name);Object beanInstance;//根据beanName去单例池中去拿该对象(前面的逻辑所有的非懒加载的单例bean都已经创建完毕了)Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}// 如果sharedInstance是FactoryBean,那么就调用getObject()返回对象beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查BeanDefinition是不是Abstract的checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了for (String dep : dependsOn) {// beanName是不是被dep依赖了,如果是则出现了循环依赖if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为valueregisterDependentBean(dep, beanName);// 创建所依赖的beantry {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 {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;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try { // session.getAttriute(beaName) setAttriObject scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end();}}// 检查通过name所获得到的beanInstance的类型是否是requiredTypereturn adaptBeanInstance(name, beanInstance, requiredType);}
进入doGetBean
函数调用的第一个方法是String beanName = transformedBeanName(name);
protected String transformedBeanName(String name) {return canonicalName(BeanFactoryUtils.transformedBeanName(name));}public static String transformedBeanName(String name) {//检查参数确保传入的参数不为空Assert.notNull(name, "'name' must not be null");// 如果传入的 'name' 不是以 FACTORY_BEAN_PREFIX 开头("&"),直接返回 'name'(说明其实名字处理就是处理名字前面的`&`符号)if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {return name;}// 如果传入的 'name' 是以 FACTORY_BEAN_PREFIX 开头,则进行进一步处理return transformedBeanNameCache.computeIfAbsent(name, beanName -> {do {//去除 FACTORY_BEAN_PREFIX 前缀,直到 'beanName' 不再以 FACTORY_BEAN_PREFIX 开头beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());}while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));// 返回处理后的 'beanName'return beanName;});}//别名处理public String canonicalName(String name) {String canonicalName = name;// Handle aliasing...String resolvedName;do {//根据用户提供的别名从this.aliasMap中获取真正的bean的名字resolvedName = this.aliasMap.get(canonicalName);if (resolvedName != null) {canonicalName = resolvedName;}}while (resolvedName != null);//返回bean的名字return canonicalName;}
transformedBeanName
函数用于处理 bean 的名称(bean name)。在 Spring 中,bean 的名称通常是由用户指定的,但在某些情况下,Spring 会根据一定的规则对 bean 的名称进行转换和规范化。
- 去除前缀 “&”: 如果传入的 name 以 “&” 开头,transformedBeanName 函数可能会去除这个前缀。在 Spring 中,“&” 常常用于获取 FactoryBean 实例而不是由该 FactoryBean 创建的对象实例。
- 处理别名: 如果 name 是一个别名,那么 transformedBeanName 可能会转换成与别名对应的规范的 bean 名称。别名是指在 Spring 容器中定义的一种 bean 别称,可以通过别名来引用相同的 bean。
如下面代码就给UserService
这个Bean起了两个别名userService1
和userService2
。别名在spring底层是用map存储的。
@Bean({"userService","userService1","userService2"})
public UserService userService(){return new UserService();
}
transformedBeanName
函数调用完后继续回到doGetBean
方法,在处理完bean的名字后,随后调用了Object sharedInstance = getSingleton(beanName);
方法,直接从单例池中去拿指定的bean。
@Override
@Nullable
public Object getSingleton(String beanName) {return getSingleton(beanName, true);
}@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {// 尝试从 singletonObjects 缓存中获取 beanName 对应的单例对象Object singletonObject = this.singletonObjects.get(beanName);// 如果在 singletonObjects 缓存中没有找到,并且当前 bean 正在创建中if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {// 尝试从 earlySingletonObjects 缓存中获取 beanName 对应的单例对象singletonObject = this.earlySingletonObjects.get(beanName);// 如果在 earlySingletonObjects 缓存中没有找到,并且允许提前引用if (singletonObject == null && allowEarlyReference) {// 使用同步块确保线程安全synchronized (this.singletonObjects) {// 重新尝试从 singletonObjects 缓存和 earlySingletonObjects 缓存中获取 beanName 对应的单例对象singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {singletonObject = this.earlySingletonObjects.get(beanName);// 如果在 earlySingletonObjects 缓存中没有找到if (singletonObject == null) {// 从 singletonFactories 缓存中获取 ObjectFactoryObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);// 如果存在对应的 ObjectFactoryif (singletonFactory != null) {// 通过 ObjectFactory 获取单例对象singletonObject = singletonFactory.getObject();// 将获取到的单例对象放入 earlySingletonObjects 缓存this.earlySingletonObjects.put(beanName, singletonObject);// 从 singletonFactories 缓存中移除this.singletonFactories.remove(beanName);}}}}}}return singletonObject;
}
这个方法的设计主要考虑了解决循环依赖
的问题,并确保在适当的时机创建和获取单例对象。它是 Spring 容器中处理单例对象的关键部分。循环依赖这里就不详细分析,考虑到我们现在的场景是初始化费非懒加载的单例bean,所以此时单例池肯定是空的,我们是拿不到东西的,所以继续回到doGetBean
方法。它后面会执行下面的代码逻辑:
else {//这里是处理循环依赖问题的就不详细分析了if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}//尝试获取父工厂BeanFactory parentBeanFactory = getParentBeanFactory();//如果父工厂不为空,且当前工厂没有这个bean的BeanDefinitionif (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {//如果父BeanFactory的类型是AbstractBeanFactory,直接调用父工作的dogetBean方法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) {return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);//如果没有父工厂就开始执行这段逻辑try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}//拿到当前beanName对应的BeanDefinitionRootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查BeanDefinition是不是Abstract的checkMergedBeanDefinition(mbd, beanName, args);//获得当前Bean所依赖的Bean对象们String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了for (String dep : dependsOn) {// beanName是不是被dep依赖了,如果是则出现了循环依赖,抛出异常 if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为valueregisterDependentBean(dep, beanName);// 创建所依赖的beantry {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}//上面将当前bean的所依赖的bean都已经创建完了,下面就开始真正创建我们当前这个bean了//判断当前bean是不是单例的if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}});beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}//判断当前bean是不是原型beanelse if (mbd.isPrototype()) {Object prototypeInstance = null;try {//在原型bean创建之前的工作beforePrototypeCreation(beanName);//实际创建beanprototypeInstance = createBean(beanName, mbd, args);}finally {//创建后做的工作afterPrototypeCreation(beanName);}//这个实际上就是调用FactoryBean的getOrbject方法,因为我们创建的Bean,可能是一个FactoryBeanbeanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}//实现其它作用域bean的逻辑else {String scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}//获得Scope对象Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try { // session.getAttriute(beaName) setAttri //从当前的作用域池中拿bean(例如ruquest.getAttributes),没有拿到就创建Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new ScopeNotActiveException(beanName, scopeName, ex);}}}catch (BeansException ex) {beanCreation.tag("exception", ex.getClass().toString());beanCreation.tag("message", String.valueOf(ex.getMessage()));cleanupAfterBeanCreationFailure(beanName);throw ex;}finally {beanCreation.end();}}
关于父工厂我给出了一个代码案例:
public static void main(String[] args) {// 创建父工厂GenericApplicationContext parentContext = new AnnotationConfigApplicationContext(ParentConfig.class);// 创建当前工厂,并设置父工厂GenericApplicationContext childContext = new GenericApplicationContext();childContext.setParent(parentContext);// 在当前工厂中注册一些 beanchildContext.registerBean(MyBean.class);// 刷新当前工厂,使配置生效childContext.refresh();// 从当前工厂获取 beanMyBean myBean = childContext.getBean(MyBean.class);myBean.doSomething();}
上面代码的逻辑就是尝试从当前的单例池中去获取我们需要的bean,如果没有获取到,就从父工厂里面尝试获取我们的bean,如果这两步都没有获取到我们需要的bean,说明在容器中我们的这个bean还没有实例化,所以,我们需要去创建我们这个bean,对于单例bean和原型bean,这里有不同的创建逻辑,我们主要分析单例bean的创建逻辑,doGetBean
调用的核心方法是:
`sharedInstance = getSingleton(beanName, () -> {try {return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}});`
首先我们分析一下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) {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 {//这个就调用了getObject方法就是调用前面的lamda表达式singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {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;}}
下面就开始分析,真正创建bean的逻辑createBean
方法
@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd; // 马上就要实例化Bean了,确保beanClass被加载了Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {//根据mdb新建一个BeanDefinitionmbdToUse = new RootBeanDefinition(mbd);//设置BeanClassmbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// 实例化前的工作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.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}
我们知道BeanDefintion中有一个属性是:
private volatile Object beanClass;
它存储的信息就是我们这个bean所对应的类型,现在我们需要创建bean,所以我们需要首先将这个类进行加载,调用的方法是Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
@Nullableprotected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)throws CannotLoadBeanClassException {try {// 如果beanClass被加载了if (mbd.hasBeanClass()) {return mbd.getBeanClass();}// 如果beanClass没有被加载if (System.getSecurityManager() != null) {return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());}else {//开始真正的加载类return doResolveBeanClass(mbd, typesToMatch);}}catch (PrivilegedActionException pae) {ClassNotFoundException ex = (ClassNotFoundException) pae.getException();throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (ClassNotFoundException ex) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);}catch (LinkageError err) {throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);}}
上面代码的逻辑就是,如果我们的bean所对应的类已经被加载,我们直接返回Class对象即可,如果没有被加载我们就调用doResolveBeanClass(mbd, typesToMatch);
进行加载
@Nullableprivate Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)throws ClassNotFoundException {//获得类加载器,这里我们是可以指定的(会获取当前类的类加载器,作为加载我们bean类型的类加载器ClassLoader beanClassLoader = getBeanClassLoader();ClassLoader dynamicLoader = beanClassLoader;boolean freshResolve = false;if (!ObjectUtils.isEmpty(typesToMatch)) {ClassLoader tempClassLoader = getTempClassLoader();if (tempClassLoader != null) {dynamicLoader = tempClassLoader;freshResolve = true;if (tempClassLoader instanceof DecoratingClassLoader) {DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;for (Class<?> typeToMatch : typesToMatch) {dcl.excludeClass(typeToMatch.getName());}}}}//拿到类的名字String className = mbd.getBeanClassName();if (className != null) {// 如果classNmae为空,解析Spring表达式,有可能直接返回了一个Class对象Object evaluated = evaluateBeanDefinitionString(className, mbd);if (!className.equals(evaluated)) {if (evaluated instanceof Class) {return (Class<?>) evaluated;}else if (evaluated instanceof String) {className = (String) evaluated;freshResolve = true;}else {throw new IllegalStateException("Invalid class name expression result: " + evaluated);}}if (freshResolve) {if (dynamicLoader != null) {try {return dynamicLoader.loadClass(className);}catch (ClassNotFoundException ex) {if (logger.isTraceEnabled()) {logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);}}}//实际加载类return ClassUtils.forName(className, dynamicLoader);}}return mbd.resolveBeanClass(beanClassLoader);}
上面代码的逻辑就是对Class对象进行加载,加载完后继续回到CreateBean
方法。接着它将我们加载后对Bean的类型信息封装到类BeanDefinition中,然后记继续往后执行,调用到 Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
做一些Bean实例化之前的工作
@Nullableprotected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {//hasInstantiationAwareBeanPostProcessors用于判断石头有类实现了InstantiationAwareBeanPostProcessor接口Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {//实例化之前的工作bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);//实例化之后的工作if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}
上面代码的两个核心就是:
//实例化之前的工作
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//实例化之后的工作
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
这里它的底层源码如下
@Nullableprotected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {//如果调用到的第一个InstantiationAwareBeanPostProcessor实例有返回值,它就不会调用后面的InstantiationAwareBeanPostProcessor,否则就继续调用return result;}}return null;}
getBeanPostProcessorCache().instantiationAware
会返回下面的instantiationAware集合
static class BeanPostProcessorCache {final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();}
集合元素封装的都是InstantiationAwareBeanPostProcessor类,而这个类就实现了BeanPostProcessor
接口
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
.........
}
BeanPostProcessor是Spring框架中的一个扩展点接口,用于在Spring容器实例化Bean、配置Bean之后,在Bean初始化前后执行自定义的逻辑。它允许开发者在Bean实例化和初始化的过程中插入自己的处理逻辑,以对Bean进行定制化操作。
BeanPostProcessor接口定义了两个方法:
- postProcessBeforeInitialization(Object bean, String beanName):
在Bean初始化方法调用之前执行。可以在这个方法中对Bean进行一些预处理或修改。 - postProcessAfterInitialization(Object bean, String beanName):
在Bean初始化方法调用之后执行。可以在这个方法中对Bean进行一些后处理,也可以在这个阶段对Bean进行进一步的修改。
继续回到CreatBean方法
try {// 实例化前的工作,如果resolveBeforeInstantiation给我们返回了一个bean,那么就会直接返回这个beanObject 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 {//doCreatBean开始实际创建beanObject beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}
完成实例化前的逻辑,下面就开始真正开始创建bean了,核心方法是 Object beanInstance = doCreateBean(beanName, mbdToUse, args);
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// 实例化bean//声明了一个 BeanWrapper 类型的变量 instanceWrapper,用于包装 Bean 的实例BeanWrapper instanceWrapper = null;//如果当前Bean的作用域是Singleton(单例),尝试从工厂缓存中获取已经创建的单例对象。这一步是为了处理可能存在的循环依赖的情况if (mbd.isSingleton()) {// 有可能在本Bean创建之前,就有其他Bean把当前Bean给创建出来了(比如依赖注入过程中)instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {//如果上一步没有获取到已创建的单例对象,则调用 createBeanInstance 方法创建Bean的实例。instanceWrapper = createBeanInstance(beanName, mbd, args);}//获取Bean的实例对象。Object bean = instanceWrapper.getWrappedInstance();//获取Bean的实例对象的类型。Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {//将解析后的Bean类型设置到Bean定义(RootBeanDefinition)中mbd.resolvedTargetType = beanType;}// 后置处理合并后的BeanDefinition// Allow post-processors to modify the merged bean definition.synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {//调用 applyMergedBeanDefinitionPostProcessors 方法,应用合并后的Bean定义的后处理器。这里会执行所有注册的BeanPostProcessor的postProcessBeforeInitialization方法。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.isTraceEnabled()) {logger.trace("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}// 如果需要提前暴露单例对象,将当前Bean的工厂方法添加到三级缓存中,以供解决循环依赖时使用。addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}//将Bean的实例对象赋值给 exposedObject 变量Object exposedObject = bean;try {//调用 populateBean 方法,对Bean的属性进行填充。populateBean(beanName, mbd, instanceWrapper);//调用 initializeBean 方法,对Bean进行初始化。这一步会触发BeanPostProcessor的postProcessAfterInitialization方法 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)) {// beanName被哪些bean依赖了,现在发现beanName所对应的bean对象发生了改变,那么则会报错String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");}}}}//注册Bean的销毁回调,以便在容器关闭时销毁Beantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}
上面代码首先会再次尝试才单例池中获取我们需要的bean,如果没有获取到就执行下面代码来创建。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<?> 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());}// BeanDefinition中添加了Supplier,则调用Supplier来得到对象Supplier<?> instanceSupplier = mbd.getInstanceSupplier();if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName);}// @Bean对应的BeanDefinitionif (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args);}// Shortcut when re-creating the same bean...// 一个原型BeanDefinition,会多次来创建Bean,那么就可以把该BeanDefinition所要使用的构造方法缓存起来,避免每次都进行构造方法推断boolean resolved = false;boolean autowireNecessary = false;if (args == null) {synchronized (mbd.constructorArgumentLock) {if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;// autowireNecessary表示有没有必要要进行注入,比如当前BeanDefinition用的是无参构造方法,那么autowireNecessary为false,否则为true,表示需要给构造方法参数注入值autowireNecessary = mbd.constructorArgumentsResolved;}}}if (resolved) {// 如果确定了当前BeanDefinition的构造方法,那么看是否需要进行对构造方法进行参数的依赖注入(构造方法注入)if (autowireNecessary) {// 方法内会拿到缓存好的构造方法的入参return autowireConstructor(beanName, mbd, null, null);}else {// 构造方法已经找到了,但是没有参数,那就表示是无参,直接进行实例化return instantiateBean(beanName, mbd);}}// 如果没有找过构造方法,那么就开始找了// Candidate constructors for autowiring?// 提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪些构造方法// 比如AutowiredAnnotationBeanPostProcessor会把加了@Autowired注解的构造方法找出来,具体看代码实现会更复杂一点Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);// 如果推断出来了构造方法,则需要给构造方法赋值,也就是给构造方法参数赋值,也就是构造方法注入// 如果没有推断出来构造方法,但是autowiremode为AUTOWIRE_CONSTRUCTOR,则也可能需要给构造方法赋值,因为不确定是用无参的还是有参的构造方法// 如果通过BeanDefinition指定了构造方法参数值,那肯定就是要进行构造方法注入了// 如果调用getBean的时候传入了构造方法参数值,那肯定就是要进行构造方法注入了if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);}// Preferred constructors for default construction?ctors = mbd.getPreferredConstructors();if (ctors != null) {return autowireConstructor(beanName, mbd, ctors, null);}// No special handling: simply use no-arg constructor.// 不匹配以上情况,则直接使用无参构造方法return instantiateBean(beanName, mbd);}
上面代码还是挺重要的,但这里我们先不详细展开讲解,我们只需要知道createBeanInstance
帮我把我们需要的bean创建出来来,然后继续回到doCreateBean
逻辑。执行 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
这里让我们在属性填充支持再次对BenaDenifition进行一些处理,如我们可以给某些属性指定自己想要的值等。接着调用populateBean(beanName, mbd, instanceWrapper);
进行真正的属性填充:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//如果 BeanWrapper 对象 bw 为 null,说明没有有效的Bean实例对象,这可能是因为之前的创建过程失败。如果Bean定义中包含属性值,抛出异常,否则跳过属性填充过程。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;}}//如果Bean定义不是合成的(非合成的Bean定义)且存在实例化后的BeanPostProcessor,遍历这些BeanPostProcessor,调用它们的postProcessAfterInstantiation方法。这一步是在属性设置之前,给BeanPostProcessor一个机会在Bean实例化后修改Bean的状态。if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}}}//获取Bean定义中定义的属性值。PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);//获取Bean定义中解析后的自动装配模式。int resolvedAutowireMode = mbd.getResolvedAutowireMode();//如果自动装配模式是按照属性名字自动装配或者按照属性类型自动装配,创建一个新的MutablePropertyValues对象,并根据相应的自动装配模式填充属性值if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {// MutablePropertyValues是PropertyValues具体的实现类MutablePropertyValues newPvs = new MutablePropertyValues(pvs);if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}//检查是否存在实例化后的BeanPostProcessor。boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();//检查是否需要进行依赖检查。boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);//初始化一个属性描述符数组,用于存储过滤后的属性描述符。PropertyDescriptor[] filteredPds = null;//如果存在实例化后的BeanPostProcessor,遍历它们,调用postProcessProperties和postProcessPropertyValues方法,处理属性值的后处理。这里主要是为了支持注解驱动的依赖注入(如@Autowired)。if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {// 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值// AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}//如果需要进行依赖检查,调用checkDependencies方法,检查Bean的依赖关系。if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs);}// 如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowiredif (pvs != null) {applyPropertyValues(beanName, mbd, bw, pvs);}}
这段代码主要负责了Bean属性的填充过程,包括处理自动装配、依赖检查和属性后处理的工作。经过上面代码处理bean的属性就填充成功了,继续回到doCreateBean
方法,继续进行Bean的初始化,exposedObject = initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {//Aware接口是一组由Spring提供的标记接口,用于标识一些特定的回调方法,这些方法在Bean实例化之后,初始化之前被调用,以便让Bean感知一些容器相关的信息。invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;// 初始化前,调用指定的init方法if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}// 初始化try {invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}// 初始化后 AOPif (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}private void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}
从上面代码我们可以看出,创建bean的过程主要有下面几个时间段:
- 实例化前调用的逻辑(
- 实例化
- 实例化后调用的逻辑
- 属性填充前调用的逻辑
- Spring自带的依赖注入(属性赋值)
- 处理@Autowire依赖注入
- 初始化前
- 初始化
- 初始化后