Spring bean 的加载
Spring 的 bean 加载
- Spring 的容器架构
[Spring 容器架构]
finishBeanFactoryInitialization(),正文下面写着 **Instantiate all remaining (non-lazy-init) singletons**
,意味着非提早加载的类,将在这一步实例化,实现类的加载。
加载流程:
-
从开始的 getbean 入口进行剖析
ApplicationContext context = new ClassPathXmlApplicationContext("配置文件 xml"); context.getBean("bean 名字");
-
1、先获取 bean,调用 AbstractBeanFactory 的 doGetBean
doGetBean 有四个参数:name:bean 的名称
requiredType:返回的类型
args:传递的结构参数
typeCheckOnly:查看类型protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { // 获取 beanName,这边有三种模式,一个是原始的 beanName,一个是加了 & 的,一个是别名 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 是否曾经创立了 Object sharedInstance = getSingleton(beanName); // 曾经创立了,且没有结构参数,进入这个办法,如果有结构参数,往 else 走,也就是说不从获取 bean,而间接创立 bean 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 + "'"); } } // 如果是一般 bean,间接返回,是 FactoryBean,返回他的 getObject bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // 没创立过 bean 或者是多例的状况或者有参数的状况 // 创立过 Prototype 的 bean,会循环援用,抛出异样,单例才尝试解决循环依赖的问题 if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); // 父容器存在,本地没有以后 beanName,从父容器取 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. // 解决后,如果是加 &,就补上 & String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else {return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { // typeCheckOnly 为 false,将 beanName 放入 alreadyCreated 中 markBeanAsCreated(beanName); } try { // 获取 BeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 抽象类查看 checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 如果有依赖的状况,先初始化依赖的 bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) {for (String dep : dependsOn) { // 查看是否循环依赖,a 依赖 b,b 依赖 a。包含传递的依赖,比方 a 依赖 b,b 依赖 c,c 依赖 a if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between'" + beanName + "'and'" + dep + "'"); } // 注册依赖关系 registerDependentBean(dep, beanName); try { // 初始化依赖的 bean getBean(dep); } catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'"+ beanName +"' depends on missing bean '"+ dep +"'", ex); } } } // Create bean instance. // 如果是单例 if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> { try { // 创立 bean return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); // 如果是一般 bean,间接返回,是 FactoryBean,返回他的 getObject bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { // 退出 prototypesCurrentlyInCreation,阐明正在创立 beforePrototypeCreation(beanName); // 创立 bean prototypeInstance = createBean(beanName, mbd, args); } finally { // 移除 prototypesCurrentlyInCreation,阐明曾经创立完结 afterPrototypeCreation(beanName); } // 如果是一般 bean,间接返回,是 FactoryBean,返回他的 getObject bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else {String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) {throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'"); } try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName); try {return createBean(beanName, mbd, args); } finally {afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope'" + scopeName + "'is not active for the current thread; consider" + "defining a scoped proxy for this bean if you intend to refer to it from a singleton", ex); } } } catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName); throw ex; } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) { try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean'" + name + "'to required type'" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
-
2、获取 beanName 而后转换名称
解析完配置后创立的 Map,应用的是 beanName 作为 key。见 DefaultListableBeanFactory:/** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256);
BeanFactory.getBean 中传入的那么,有可能是这几种状况:
-
1.bean name,能够间接获取到定义 BeanDefinition。
// 转化 bean protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException {String beanName = this.transformedBeanName(name); Object sharedInstance = this.getSingleton(beanName); Object bean; .......
-
2.alias name,别名,须要转化。
如果是 alias name,在解析阶段,alias name 和 bean name 的映射关系被注册到 SimpleAliasRegistry 中。从该注册器中取到 beanName。见 SimpleAliasRegistry.canonicalName:public String canonicalName(String name) { String canonicalName = name; String resolvedName; do {resolvedName = (String)this.aliasMap.get(canonicalName); if (resolvedName != null) {canonicalName = resolvedName;} } while(resolvedName != null); return canonicalName; }
-
3.factorybean name, 带 & 前缀,通过它获取 BeanDefinition 的时候须要去除 & 前缀。
如果是 factorybean name,示意这是个工厂 bean,有携带前缀修饰符&
的,间接把前缀去掉。见BeanFactoryUtils.transformedBeanName
:public static String transformedBeanName(String name) {Assert.notNull(name, "'name' must not be null"); return !name.startsWith("&") ? name : (String)transformedBeanNameCache.computeIfAbsent(name, (beanName) -> { do {beanName = beanName.substring("&".length()); } while(beanName.startsWith("&")); return beanName; }); }
-
-
3、合并 RootBeanDefinition(合并本地的 bean)
从配置文件读取的 BeanDefinition 是 GenericBeanDefinition 它的记录了一些以后类申明的属性或结构参数,然而对于父类只用了一个 parentName 来记录。public class GenericBeanDefinition extends AbstractBeanDefinition { ... private String parentName; ... }
实例化 Bean 的时候,应用的 BeanDefinition 是 RootBeanDefinition 类型而非 GenericBeanDefinition。
-
GenericBeanDefinition 在有继承关系的状况下,定义的信息有余:
如果不存在继承关系,GenericBeanDefinition 存储的信息是残缺的,能够间接转化为 RootBeanDefinition。
如果存在继承关系,GenericBeanDefinition 存储的是 增量信息 而不是 全量信息。-
实际上干活的还是 AbstractBeanFactory.doGetBean
protected <T> T doGetBean ... { ... // 合并父类定义 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); ... // 应用合并后的定义进行实例化 bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); ... }
-
在判断 parentName 存在的状况下,阐明存在父类定义,启动合并。如果父类还有父类,递归调用,持续合并。
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException { ... String parentBeanName = transformedBeanName(bd.getParentName()); ... // 递归调用,持续合并父类定义 pbd = getMergedBeanDefinition(parentBeanName); ... // 应用合并后的残缺定义,创立 RootBeanDefinition mbd = new RootBeanDefinition(pbd); // 应用以后定义,对 RootBeanDefinition 进行笼罩 mbd.overrideFrom(bd); ... return mbd; }
每次合并完父类定义后,都会调用 RootBeanDefinition.overrideFrom 对父类的定义进行笼罩,获取到以后类可能正确实例化的 全量信息。
-
-
解决循环依赖的问题 (临时说一下,当前详细分析)
假如 TestA 中须要注入 TestB,TestB 中须要注入 TestA。
对象创立胜利后,会在 singletonFactories 中保留一个对象工厂 ObjectFactory,调用这个 ObjectFactory 的 getObject()就能够在任何中央获取刚创立的对象。
这样当 TestB 在获取 TestA 的时候,发现 singletonFactories 中有个工厂能够获取到 TestA,那么就间接调用他,最初会进入上面这个办法protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = getBeanPostProcessorCache().smartInstantiationAware; for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {exposedObject = bp.getEarlyBeanReference(exposedObject, beanName); } } return exposedObject; }
所有实现了 SmartInstantiationAwareBeanPostProcessor 接口类的 getEarlyBeanReference()尝试做最初的批改,这个办法返回的只是传递过去的对象。
这样依赖循环就解决了。
-
-
4、创立实例
获取到残缺的 RootBeanDefintion 后,就能够拿这份定义信息来实例具体的 Bean。(创立实例由 AbstractAutowireCapableBeanFactory 接手,在 spring 容器架构外面有具体内容)
源码解析:具体实例创立见 AbstractAutowireCapableBeanFactory.createBeanInstance// 调用解析办法解析转进来的 Bean Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]); // 如果传入的不为空并且修饰符不是公开的(获取两个对象的润饰权限)也就是不为空的时判断是否有他们的拜访权限 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()); } else { // 是否有其余的类将本地 bean 实例了 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); // 如果不为空就就意味着他曾经被实例化间接返回曾经被其余调用者实例化办法 if (instanceSupplier != null) {return this.obtainFromSupplier(instanceSupplier, beanName); // 如果不为空就意味着被工厂办法调用实例化间接返回办法,被工厂办法应用实例化了 } else if (mbd.getFactoryMethodName() != null) {return this.instantiateUsingFactoryMethod(beanName, mbd, args); } else { // 判断是否曾经解析过了 boolean resolved = false; // 为 false 阐明无参,true 有参 boolean autowireNecessary = false; if (args == null) {synchronized(mbd.constructorArgumentLock) { // 如果曾经被解析过了 if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } // 解析过了,依据是否有参数抉择无参结构还是有参结构 if (resolved) {return autowireNecessary ? this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null) : this.instantiateBean(beanName, mbd); } // 依据 bean 的定义解析参数 else {Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)) {ctors = mbd.getPreferredConstructors(); return ctors != null ? this.autowireConstructor(beanName, mbd, ctors, (Object[])null) : this.instantiateBean(beanName, mbd); } // 结构器注入 else {return this.autowireConstructor(beanName, mbd, ctors, args); } } } } }
-
返回 Bean 的包装类 BeanWrapper,一共有三种策略:
-
应用工厂办法创立,instantiateUsingFactoryMethod 。
应用工厂办法创立,会先应用 getBean 获取工厂类,而后通过参数找到匹配的工厂办法,调用实例化办法实现实例化,具体见ConstructorResolver.instantiateUsingFactoryMethod:public BeanWrapper instantiateUsingFactoryMethod ... ( ... String factoryBeanName = mbd.getFactoryBeanName(); ... factoryBean = this.beanFactory.getBean(factoryBeanName); ... // 匹配正确的工厂办法 ... beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(...); ... bw.setBeanInstance(beanInstance); return bw; }
-
应用无参构造函数创立,instantiateBean。
应用无参构造函数创立是最简略的形式,见 AbstractAutowireCapableBeanFactory.instantiateBean:protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { try { Object beanInstance; final BeanFactory parent = this; if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, parent), getAccessControlContext()); } else { // 创立一个 bean beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent); } // 初始化 BeanWrapper 并返回 BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
-
应用有参构造函数创立,autowireConstructor。
应用有参构造函数创立,整个过程比较复杂,波及到参数和结构器的匹配。为了找到匹配的结构器,Spring 花了大量的工作,见 ConstructorResolver.autowireConstructor:public BeanWrapper autowireConstructor ... { ... Constructor<?> constructorToUse = null; ... // 匹配构造函数的过程 ... beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(...); ... bw.setBeanInstance(beanInstance); return bw; }
-
-
拿到了构造函数,并没有立刻实例化。因为用户应用了 replace 和 lookup 的配置办法,用到了动静代理退出对应的逻辑。如果没有的话,间接应用反射来创立实例。创立实例后,就能够开始注入属性和初始化等操作。如果是 FactoryBean 的话须要应用 getObject 办法来创立实例。见 AbstractBeanFactory.getObjectForBeanInstance,会执行到 FactoryBeanRegistrySupport.doGetObjectFromFactoryBean。- getObjectForBeanInstance 源码:```Java
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.
// 如果 beanname 是 & 结尾的,这个 bean 必须是 FactoryBean 类型
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.
// 一般 bean 或者 beanname 是 & 结尾的,返回 beanInstance
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}
// 是 FactoryBean 然而没有 & 结尾的
Object object = null;
if (mbd == null) {
// bean 的定义信息是空的,从缓存中拿
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.
// mdb 为空,并且曾经实例化过
if (mbd == null && containsBeanDefinition(beanName)) {mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义的,而不是程序自身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);// 返回 factory 的 getObject 办法
}
return object;
}
```
- doGetObjectFromFactoryBean 源码:```Java
// 调用 factoryBean 的 getObjectType 办法返回对象
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {if (System.getSecurityManager() != null) {AccessControlContext acc = getAccessControlContext();
try {object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {throw pae.getException();
}
}
else {object = factory.getObject();// 调用 factoryBean 的 getObjectType 办法返回对象
}
}
catch (FactoryBeanNotInitializedException ex) {throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
}
// 没获取到对象,返回 NullBean
object = new NullBean();}
return object;
}
```
-
5、注入属性
-
实例创立完后开始进行属性的注入,如果波及到内部依赖的实例,会自动检索并关联到该以后实例。入口办法在AbstractAutowireCapableBeanFactory.populateBean。
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {if (bw == null) { // 如果 BeanWrapper 为空,然而有属性值,就跑异样 if (mbd.hasPropertyValues()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. // 看看 InstantiationAwareBeanPostProcessors 是否有注入值,如果有注入,就不持续注入,间接返回 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) {return;} PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) { // 拷贝配置信息 MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. // 依据名称注入 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. // 依据类型注入 if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } // r 容器是否有 InstantiationAwareBeanPostProcessors boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); // 是否进行依赖查看 boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues(); } // 后置解决 for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) {return;} } pvs = pvsToUse; } } } if (needsDepCheck) {if (filteredPds == null) { // 过滤出须要依赖查看的属性 filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 查看依赖关系,保障依赖项已初始化 checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 此时才开始赋值 applyPropertyValues(beanName, mbd, bw, pvs); } }
利用 InstantiationAwareBeanPostProcessor 处理器,在属性注入前后进行解决。假如咱们应用了 @Autowire 注解,这里会调用到 AutowiredAnnotationBeanPostProcessor 来对依赖的实例进行检索和注入的,它是 InstantiationAwareBeanPostProcessor 的子类。
依据名称或者类型进行主动注入,存储后果到 PropertyValues 中。
利用 PropertyValues,填充到 BeanWrapper。这里在检索依赖实例的援用的时候,会递归调用 BeanFactory.getBean 来取得。
-
-
6、初始化
-
1、触发 Aware,Spring 在初始化阶段,如果判断 Bean 实现了这几个接口之一,就会往 Bean 中注入它关怀的资源。见 AbstractAutowireCapableBeanFactory.invokeAwareMethos :
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean); // 如果是 InitializingBean 并且有 afterPropertiesSet,调用 afterPropertiesSet 办法 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name'" + beanName + "'"); } 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();} } // 如果是 InitializingBean,但没有 afterPropertiesSet,调用自定义的办法 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); } } }
-
2、触发 BeanPostProcessor,Spring 框架提供了 BeanPostProcessor 来达成这个指标。
/** BeanPostProcessors to apply in createBean */ private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>();
Bean 实例化前后,Spring 会去调用咱们曾经注册的 beanPostProcessors 把处理器都执行一遍。
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 获取 BeanPostProcessor 解决 for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessBeforeInitialization(result, beanName); if (current == null) {return result;} result = current; } return result; }
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; // 获取 BeanPostProcessor 解决 for (BeanPostProcessor processor : getBeanPostProcessors()) {Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) {return result;} result = current; } return result; }
这里应用了责任链模式,Bean 会在处理器链中进行传递和解决。当咱们调用 BeanFactory.getBean 的后,执行到 Bean 的初始化办法 AbstractAutowireCapableBeanFactory.initializeBean 会启动这些处理器。
public Object initializeBean(Object existingBean, String beanName) {return initializeBean(beanName, existingBean, null); } protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 调用 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; 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); } if (mbd == null || !mbd.isSynthetic()) { // 后置处理器 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
-
3、触发自定义 init
自定义初始化有两种形式能够抉择:
实现 InitializingBean。提供了一个很好的机会,在属性设置实现后再退出本人的初始化逻辑。定义 init 办法。自定义的初始化逻辑。见 AbstractAutowireCapableBeanFactory.invokeInitMethods:protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean); // 如果是 InitializingBean 并且有 afterPropertiesSet,调用 afterPropertiesSet 办法 if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isTraceEnabled()) {logger.trace("Invoking afterPropertiesSet() on bean with name'" + beanName + "'"); } 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();} } // 如果是 InitializingBean,但没有 afterPropertiesSet,调用自定义的办法 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); } } }
-
-
7、类型转换
Bean 曾经加载结束,属性也填充好了,初始化也实现了。
在返回给调用者之前,还留有一个机会对 Bean 实例进行类型的转换。见 AbstractBeanFactory.doGetBean:// 调用 dogetBean 办法 // 以下办法根本都是对 dogetbean 参数的判断 protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { // 获取 bean 后将转换后的 bean 赋值给 beanName String beanName = this.transformedBeanName(name); Object bean; // 获取上方单例 bean Object sharedInstance = this.getSingleton(beanName); // 判断是否有单例 BEAN,如果有 BEAN 并且没有 args 参数进入此办法 if (sharedInstance != null && args == null) { // 判断是否启用日志追踪 if (this.logger.isTraceEnabled()) { // 判断获取的单例 bean 是否曾经加载了 if (this.isSingletonCurrentlyInCreation(beanName)) { // 在日志外面记录这条音讯 this.logger.trace("Returning eagerly cached instance of singleton bean'" + beanName + "'that is not fully initialized yet - a consequence of a circular reference"); // 如果获取的单例 bean 没有加载就纪录这条 } else {this.logger.trace("Returning cached instance of singleton bean'" + beanName + "'"); } } // 一般的 bean 间接返回 FactoryBean,返回他的 getObject bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null); // 如果没有单例 BEAN,或者有 BEAN 并且有 args 参数进入此办法 } else { // 没创立过 bean 或者是多例的状况或者有参数的状况 // 创立过 Prototype 的 bean,会循环援用,抛出异样,单例才尝试解决循环依赖的问题 if (this.isPrototypeCurrentlyInCreation(beanName)) { // 就抛出异样 Bean 以后正在创立异样 throw new BeanCurrentlyInCreationException(beanName); } // 获取父类工厂 BeanFactory parentBeanFactory = this.getParentBeanFactory(); // 如果父类工厂不为空,beanName 不存在也就是没有拿到本地的 bean if (parentBeanFactory != null && !this.containsBeanDefinition(beanName)) { // 给调用者原始 bean String nameToLookup = this.originalBeanName(name); // 如果父类工厂实例形象 bean 工厂 if (parentBeanFactory instanceof AbstractBeanFactory) { // 返回形象形象 bean 工厂的父类工厂,调用 dogetbean 办法 return ((AbstractBeanFactory)parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly); } // 如果参数不为空 if (args != null) {return parentBeanFactory.getBean(nameToLookup, args); } // requiredType:返回的类型 if (requiredType != null) {return parentBeanFactory.getBean(nameToLookup, requiredType); } // nameToLookup 要查找的名称 return parentBeanFactory.getBean(nameToLookup); } // 如果查看类型不为空 if (!typeCheckOnly) { // markBeanAsCreated 将 Bean 标记为已创立 this.markBeanAsCreated(beanName); } try { // 获取本地的 BeanDefinition(获取合并的本地 Bean 定义也即是 BeanDefinition)RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName); // 查看合并 BeanDefinition this.checkMergedBeanDefinition(mbd, beanName, args); // 通过本地的 BeanDefinition 获取他的依赖 String[] dependsOn = mbd.getDependsOn(); String[] var11; // 如果依赖不为空 if (dependsOn != null) { // 将获取的依赖给数组赋值 var11 = dependsOn; // 将依赖的大小作为界值 int var12 = dependsOn.length; // 循环赋值 for(int var13 = 0; var13 < var12; ++var13) {String dep = var11[var13]; // 查看是否循环依赖,a 依赖 b,b 依赖 a。包含传递的依赖,比方 a 依赖 b,b 依赖 c,c 依赖 a if (this.isDependent(beanName, dep)) { // 抛出异样,单例才尝试解决循环依赖的问题 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between'" + beanName + "'and'" + dep + "'"); } // 注册依赖关系 this.registerDependentBean(dep, beanName); try { // 以后调用者获取依赖 this.getBean(dep); bean 的定义异样 } catch (NoSuchBeanDefinitionException var24) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'"+ beanName +"' depends on missing bean '"+ dep +"'", var24); } } } // 如果本地的 BeanDefinition 是单例 if (mbd.isSingleton()) { // 给调用者创立一个 BeanDefinition sharedInstance = this.getSingleton(beanName, () -> { try { // 创立 bean return this.createBean(beanName, mbd, args); // bean 异样,销毁 } catch (BeansException var5) {this.destroySingleton(beanName); throw var5; } }); // 如果是一般 bean,间接返回,是 FactoryBean,返回他的 getObject bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd); // 本地 BeanDefinition 是最后的 bean(就是原型 bean)} else if (mbd.isPrototype()) { var11 = null; // 定义一个原型 bean Object prototypeInstance; try { // 退出一个 prototypesCurrentlyInCreation this.beforePrototypeCreation(beanName); // 在创立原型 bean 前创立一个 beanBeanDefinition prototypeInstance = this.createBean(beanName, mbd, args); // 最终移除 prototypesCurrentlyInCreation } finally {this.afterPrototypeCreation(beanName); } // 如果是一般 bean,间接返回,是 FactoryBean,返回他的 getObject bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 获取本地的 BeanDefinition 的作用域 String scopeName = mbd.getScope(); // 通过全局作用域获取以后 bean Scope scope = (Scope)this.scopes.get(scopeName); // 如果作用域为空则 bean 不存在 if (scope == null) { // 抛出异样,bean 状态异样 throw new IllegalStateException("No Scope registered for scope name'" + scopeName + "'"); } try { // 退出一个 prototypesCurrentlyInCreation Object scopedInstance = scope.get(beanName, () -> { // 在创立原型 bean 前创立一个 beanBeanDefinition this.beforePrototypeCreation(beanName); Object var4; try {var4 = this.createBean(beanName, mbd, args); // 最终移除 prototypesCurrentlyInCreation } finally {this.afterPrototypeCreation(beanName); } return var4; }); // 如果是一般 bean,间接返回,是 FactoryBean,返回他的 getObject bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } catch (IllegalStateException var23) {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", var23); } } } catch (BeansException var26) {this.cleanupAfterBeanCreationFailure(beanName); throw var26; } } // 如果类型不为空,beanName 不存在也就是没有拿到本地的 bean if (requiredType != null && !requiredType.isInstance(bean)) { try { // 调用类型转换器进行 bean 的转换 T convertedBean = this.getTypeConverter().convertIfNecessary(bean, requiredType); 如果转换后的 bean 还是为空 if (convertedBean == null) { // 抛出 bean 类型异样 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); // 间接返回转换后的 bean } else {return convertedBean;} // 抛出类型匹配异样 } catch (TypeMismatchException var25) { // 调用日志类进行记录 if (this.logger.isTraceEnabled()) { // 写入日志信息 this.logger.trace("Failed to convert bean'" + name + "'to required type'" + ClassUtils.getQualifiedName(requiredType) + "'", var25); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } else {return bean;} }