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; } }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。