经过上篇的分析 , 我们已经完成了Bean实例的注册流程解析 , 已经将XML文件内容解析成一个个的 BeanDefinition 实例存在于容器之中 。接下来就可以调用 BeanFactory的getBean 方法获取目标 Bean 实例 。
public class SpringClient {public static void main(String[] args) {// 类路径下的资源 将其具体抽象成资源对象Resource resource = new ClassPathResource("applicationContext.xml");// 创建Bean工厂实例DefaultListableBeanFactory defaultListableBeanFactory = new DefaultListableBeanFactory();// 创建bean读取器实例BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(defaultListableBeanFactory);// 将读取的资源放到defaultListableBeanFactory工厂当中beanDefinitionReader.loadBeanDefinitions(resource);// 读取完 , 我们需要哪个对象找工厂要Student student = (Student) defaultListableBeanFactory.getBean("student");Student student2 = (Student) defaultListableBeanFactory.getBean("student");System.out.println(student.getAge());System.out.println(student.getName());System.out.println(student == student2);}} Spring 提供了多种重载和覆盖的 getBean 方法 , 当我们在执行 defaultListableBeanFactory.getBean(“student”);时 , 我们实际上是在调用 AbstractBeanFactory 中的实现:
@Overridepublic Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false);}@Overridepublic T getBean(String name, Class requiredType) throws BeansException { return doGetBean(name, requiredType, null, false);}@Overridepublic Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false);}public T getBean(String name, @Nullable Class requiredType, @Nullable Object... args)throws BeansException { return doGetBean(name, requiredType, args, false);} 一个真正干活的函数其实是以 do 开头的 , doGetBean 方法也不例外 , 其中包含了整个创建和获取 bean 的过程 。
/*返回指定bean的实例 , 该实例可以是共享的 , 也可以是独立的 。*/protected T doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException { /** 提取对应的beanName** 因为传入的参数可以是 alias , 也可能是 FactoryBean 的 name , 所以需要进行解析 , 包含以下内容:* 1. 如果是 FactoryBean , 则去掉 “&” 前缀* 2. 沿着引用链获取 alias 对应的最终 name*/ String beanName = transformedBeanName(name); Object beanInstance; /** 检查缓存中或者实例工厂中是否有对应的实例* 为什么首先会使用这段代码呢?* 因为在创建单例 bean的时候会存在依赖注入的情况 , 而在创建依赖的时候为了避免循环依赖 , * Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光* 也就是将 ObjectFactory 加入到缓存中 , 一旦下个bean创建时候需要依赖上个 bean则直接使用* ObjectFactory*/ // 直接尝试从缓存获取 或者singletonFactories 中的 ObjectFactory中获取 // Eagerly check singleton cache for manually registered singletons. 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 + "'");}}// 返回对应的实例beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 目标实例不存在 else {/** 只有在单例情况才会尝试解决循环依赖 , 原型模式情况下 , 如果存在* A中有B的属性 , B中有A的属性 , 那么当依赖注入的时候 , 就会产生当A还未创建完的时候因为* 对于B的创建再次返回创建A , 造成循环依赖 , 也就是下面的情况* isPrototypeCurrentlyInCreation (beanName)为 true*/if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}BeanFactory parentBeanFactory = getParentBeanFactory();// 如果 beanDefinitionMap中也就是在所有已经加载的类中不包括 beanName 则尝试从parentBeanFactory中检测if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {String nameToLookup = originalBeanName(name);// 递归到父 BeanFactory 中进行检索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);}}// 如果不是仅仅做类型检查则是创建bean , 这里要进行记录(将指定的bean标记为已创建(或即将创建) 。)if (!typeCheckOnly) {markBeanAsCreated(beanName);}StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate").tag("beanName", name);try {if (requiredType != null) {beanCreation.tag("beanType", requiredType::toString);}// 将存储XML配置的GenericBeanDefinition实例转换成RootBeanDefinition实例// 如果存在父bean , 则同时合并父bean的相关属性RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);String[] dependsOn = mbd.getDependsOn();// 若存在依赖其它的bean则需要递归实例化依赖的 beanif (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {// 检查是否存在循环依赖throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// 缓存依赖调用registerDependentBean(dep, beanName);try {getBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// 实例化依赖的bean后便可以实例化 mbd本身了// singleton 模式的创建// scope == singleton// Create bean instance.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);}else if (mbd.isPrototype()) {// scope == prototypeObject prototypeInstance = null;try {// 设置正在创建的状态beforePrototypeCreation(beanName);// 创建beanprototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}// 返回对应的实例beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {// 其它scopeString 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 {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();} } return adaptBeanInstance(name, beanInstance, requiredType);}// 检查需要的类型是否符合bean 的实际类型 对应getBean时指定的requireType@SuppressWarnings("unchecked") T adaptBeanInstance(String name, Object bean, @Nullable Class> requiredType) { // Check if required type matches the type of the actual bean instance. if (requiredType != null && !requiredType.isInstance(bean)) {try {Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return (T) 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;} 【Spring源码解析:Bean的加载流程】对于Bean加载过程中所涉及的步骤大致如下:
- 将参数 name 转换成对应的真实 beanName
- 检查缓存中或者实例工厂中是否有对应的实例 , 若存在则进行实例化并返回对象 , 否则继续往下执
- 如果是获取 prototype 类型对象 , 则检查依赖关系 , 防止出现循环依赖;
- 如果 beanDefinitionMap中也就是在所有已经加载的类中不包括 beanName 则尝试从parentBeanFactory中检测
- 将之前解析过程返得到的 GenericBeanDefinition 对象合并为 RootBeanDefinition 对象 , 如果存在父bean , 则同时合并父bean的相关属性
- 若存在依赖其它的bean则需要递归实例化依赖的 bean
- 依据当前 bean 的作用域对 bean 进行实例化
- 如果对返回 bean 类型有要求 , 则进行类型检查 , 并做类型转换 。
- 返回 bean 实例 。
@Override@Nullablepublic Object getSingleton(String beanName) { return getSingleton(beanName, true);}@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// 检查缓存中是否存在实例// singletonObjects:用于保存BeanName和创建bean实例之间的关系,beanName --> beanInstance Object singletonObject = this.singletonObjects.get(beanName); // 实例不存在 && 正在创建中 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {/** earlySingletonObjects: 也是保存 BeanName 和创建 bean 实例之间的关系* 与singletonObjects 的不同之处在于 , 当一个单例 bean 被放到这里面后 , * 那么当bean还在创建中就可以通过 getBean 方法获取到了 , 其目的是用来检测循环引用 。* 也就是Bean实例还处于创建中*/singletonObject = this.earlySingletonObjects.get(beanName);// 如果bean在加载中 则不处理if (singletonObject == null && allowEarlyReference) {synchronized (this.singletonObjects) {// 再次检查缓存 双重检查singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null) {// 再次检查bean是否再创建中singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null) {// 当某些方法需要提前初始化的时候 , 会调用addSingletonFactory将对应的objectFactory初始化策略存储在singletonFactories中ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 调用预先设定的 getobject方法singletonObject = singletonFactory.getObject();// 记录在缓存中,earlySingletonObjects 和 singletonFactories互斥this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}} } return singletonObject;} 这个方法首先尝试从 singletonObjects 里面获取实例,如果获取不到再从 earlySingletonObjects 里面获取,如果还获取不到,再尝试从 singletonFactories 里面获取 beanName 对应的 ObjectFactory,然后调用这个 ObjectFactory 的 getObject 来创建 bean,并放到 earlySingletonObjects里面去,并且从 singletonFactories里面 remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference 为 true的情况下才 会使用.这里涉及用于存储 bean的不同的map,简单解释如下:
singletonObjects:单例对象的缓存,用于保存BeanName 和创建bean 实例之间的关系,beanName -> beanInstance
singletonFactories:用于保存BeanName和创建 bean 的工厂之间的关系,beanName ->ObjectFactory.
earlySingletonObjects: 也是保存BeanName 和创建 bean 实例之间的关系 , 与 singletonObjects 的不同之处在于 , 当一个单例 bean 被放到这里面后 , 那么当 bean 还 在创建过程中 , 就可以通过 getBean 方法获取到了 , 其目的是用来检测循环引用 。
registeredSingletons:用来保存当前所有已注册的 bean 。
2.获取单例 如果在上一步 缓存中没有获取到单例 bean , 那么就需要从头开始 bean 的加载过程了 , 而 Spring 中使用 getSingleton 的重载方法实现bean的加载过程 。
// Create bean instance.if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> {try {// 创建bean 的真正逻辑return createBean(beanName, mbd, args);}catch (BeansException ex) {// 出现异常 清理工作 , 从单例缓存中移除destroySingleton(beanName);throw ex;} }); beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);} /*返回以给定名称注册的单例对象 , 如果尚未注册 , 则创建并注册一个新的单例对象 。*/public Object getSingleton(String beanName, ObjectFactory> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); //全局变量需要加锁 synchronized (this.singletonObjects) {// singletonObjects用于缓存beanName与已创建的单例对象的映射关系// 首先检查对应的bean是否已经加载过 , 因为singleton 模式其实就是复用以创建的 bean , // 所以这一步是必须的Object singletonObject = this.singletonObjects.get(beanName);// 如果为空才可以进行singleto的 bean 的初始化if (singletonObject == null) {// 当前单例对象是否处于销毁状态if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while singletons of this factory are in destruction " +"(Do not request a bean from a BeanFactory in a destroy method implementation!)");}if (logger.isDebugEnabled()) {logger.debug("Creating shared instance of singleton bean '" + beanName + "'");}// 前置处理 , 设置状态为“正在创建中”beforeSingletonCreation(beanName);// 标识bean是否创建成功boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}try {// 初始化bean执行的是传进来的 lambda 表达式singletonObject = singletonFactory.getObject();// 创建成功 标识改为truenewSingleton = 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的方法其实并不是在此方法中实现的 , 其实现逻辑是在ObjectFactory 类型的实例singletonFactory中实现的 。而这些准备及处理操作包括如下内容 。1.检查缓存是否已经加载过 。
2.若没有加载 , 则将 bean 设置状态为“正在创建中” , 可以对循环依赖进行检测 。
3.实例化 bean , 如果过程中出现异常 , 则再次尝试从缓存中获取实例
4.后置处理 , 移除“bean正在创建中”的状态
5.将结果记录至缓存并删除加载bean 过程中所记录的各种辅助状态 。
protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) {this.singletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);this.earlySingletonObjects.remove(beanName);this.registeredSingletons.add(beanName); }} 创建bean 的真正逻辑位于ObjectFactory 的核心部分其createBean 方法,所以我们还需要到 createBean进行探索 。3.创建Bean
@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; // 根据设置的class属性或者根据className 来解析 Class (拿到Class对象) Class> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass); } try {// 对override属性进行标记和验证 , 本质上是处理lookup-method和replaced-method标签mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex); } try {// BeanPostProcessors 个机会来返回代理来替代真正的实例Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {// 当经过前置处理后返回的结果如果不为空 , 那么会直接略过后续的Bean 的创建return bean;} } catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex); } try {// 创建bean实例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); }} 一个真正干活的函数其实是以do 开头的 , 这个规则对于 createBean 也不例外 , createBean方法主要还是在做一些前期准备工作 。而常规bean的创建就是在 doCreateBean中完成的 。protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException { // BeanWrapper 可以看作是偏底层的 bean 包装器 , 提供了对标准 java bean 的分析和操作方法 , 包括获取和设置属性值、获取属性描述符 , 以及属性的读写特性等 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) {// 如果是单例则需要首先清除缓存instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } // bean未实例化 , 创建 bean 实例 if (instanceWrapper == null) {/** 根据指定bean 使用对应的策略创建新的实例 , 如:工厂方法、构造函数自动注入、简单初始化* 将beanDefinition转成BeanWrapper , 大致流程如下:* 1. 如果存在工厂方法 , 则使用工厂方法初始化* 2. 否则 , 如果存在多个构造函数 , 则根据参数确定构造函数 , 并利用构造函数初始化* 3. 否则 , 使用默认构造函数初始化*/instanceWrapper = createBeanInstance(beanName, mbd, args); } // 从BeanWrapper中获取包装的bean实例 Object bean = instanceWrapper.getWrappedInstance(); // 从BeanWrapper获取包装bean的Class对象 Class> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType; } // 应用 MergedBeanDefinitionPostProcessor synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;} } // 是否需要提早曝光:单例&&允许循环依赖&&当前bean正在创建中 , 检测循环依赖 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初始化完成前将创建实例的ObjectFactory 加入工厂addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // 初始化bean实例 Object exposedObject = bean; try {//对bean进行填充 , 将各个属性值注入 , 如果存在依赖的bean则进行递归初始化populateBean(beanName, mbd, instanceWrapper);// 调用初始化方法,比如 init-methodexposedObject = initializeBean(beanName, exposedObject, mbd); } catch (Throwable ex) {if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {throw (BeanCreationException) ex;}else {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);} } if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空if (earlySingletonReference != null) {// 如果exposedObject 没有在初始化方法中被改变 , 也就是没有被增强if (exposedObject == bean) {exposedObject = earlySingletonReference;}else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {// 获取依赖的bean的nameString[] dependentBeans = getDependentBeans(beanName);Set actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);for (String dependentBean : dependentBeans) {if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {// 检测依赖 , 记录未完成创建的beanactualDependentBeans.add(dependentBean);}}// 因为bean在创建完成之后 , 其依赖的bean一定是被创建了的// 如果actualDependentBeans不为空 , 则说明bean依赖的bean没有完成创建 , 存在循环依赖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.");}}} } try {// 注册DisposableBeanregisterDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject;} 我们看看整个函数的概要思路:1.如果是单例则需要首先清除缓存 。
2.实例化 bean, 将 BeanDefinition 转换为BeanWrapper
3.MergedBeanDefinitionPostProcessor 的应用
4.依赖处理:在 Spring 中会有循环依赖的情况 , 例如 , 当A中含有B的属性 , 而B中又含有A的属性 时就会构成一个循环依赖 , 此时如果A和B都是单例 , 那么在Spring 中的处理方式就是当创 建B的时候 , 涉及自动注入A的步骤时 , 并不是直接去再次创建A , 而是通过放入缓存中的 ObjectFactory来创建实例 , 这样就解决了循环依赖的问题 。
5.属性填充 。将所有属性填充至 bean 的实例中
6.循环依赖检查:之前有提到过 , 在 Sping中解决循环依赖只对单例有效 , 而对于prototype 的 bean , Spring 没有好的解决办法 , 唯一要做的就是抛出异常 。在这个步骤里面会检测已经加载的bean 是否 已经出现了依赖循环 , 并判断是否需要抛出异常 。
7.注册DisposableBean
创建Bean实例createBeanInstance
将 BeanDefinition 转换为BeanWrapper
使用适当的实例化策略为指定的bean创建一个新实例:工厂方法、构造函数自动注入、简单初始化
// 使用适当的实例化策略为指定的bean创建一个新实例:工厂方法、构造函数自动注入、简单初始化protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 解析Class Class> beanClass = resolveBeanClass(mbd, beanName); // 判断是否允许被创建 , 不允许则直接抛异常 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } Supplier> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) {return obtainFromSupplier(instanceSupplier, beanName); } // 如果工厂方法不为空则使用工厂方法初始化策略 if (mbd.getFactoryMethodName() != null) {return instantiateUsingFactoryMethod(beanName, mbd, args); } // 利用构造函数进行实例化 , 解析并确定目标构造函数 boolean resolved = false; boolean autowireNecessary = false; if (args == null) {synchronized (mbd.constructorArgumentLock) {// 一个类可能有多个构造函数 , 需要根据参数来确定具体的构造函数if (mbd.resolvedConstructorOrFactoryMethod != null) {resolved = true;autowireNecessary = mbd.constructorArgumentsResolved;}} } // 如果已经解析过 , 则使用已经确定的构造方法 if (resolved) {if (autowireNecessary) {// 依据构造函数注入return autowireConstructor(beanName, mbd, null, null);}else {// 使用默认构造函数构造return instantiateBean(beanName, mbd);} } // 需要根据参数决定使用哪个构造函数 Constructor>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args); } ctors = mbd.getPreferredConstructors(); if (ctors != null) {// 构造函数自动注入return autowireConstructor(beanName, mbd, ctors, null); } // 使用默认构造函数构造 无参构造器 return instantiateBean(beanName, mbd);} 我们这里看下使用默认构造函数实例化给定bean 。protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try {Object beanInstance;if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged((PrivilegedAction 到这里得到的也仅仅是一个 bean 的最初实例 , 还不是我们最终期望的 bean , 因为后面还需要对 bean 实例进行初始化处理 , 注入相应的属性值等 。属性注入populateBean
将所有属性填充至 bean 的实例中
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) {if (mbd.hasPropertyValues()) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");}else {return;} } if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {return;}} } // 属性集合 age 和 name PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {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;} } if (needsDepCheck) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) {// 属性值设值applyPropertyValues(beanName, mbd, bw, pvs); }} applyPropertyValues属性值设值protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) { // 为空直接返回 if (pvs.isEmpty()) {return; } if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext()); } MutablePropertyValues mpvs = null; List original; if (pvs instanceof MutablePropertyValues) {mpvs = (MutablePropertyValues) pvs;// 如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanwapper 中if (mpvs.isConverted()) {try {bw.setPropertyValues(mpvs);return;}catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);}}// 拿到属性名 和 属性值 age name 26 zhangsanoriginal = mpvs.getPropertyValueList(); } else {// 如果pvs并不是使用MutablePropertyValues封装的类型 , 那么直接使用原始的属性获取方法original = Arrays.asList(pvs.getPropertyValues()); } TypeConverter converter = getCustomTypeConverter(); if (converter == null) {converter = bw; } // 获取对应解析器 BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter); List deepCopy = new ArrayList<>(original.size()); boolean resolveNecessary = false; // 遍历属性 , 将属性转换为对应类的对应属性的类型 for (PropertyValue pv : original) {if (pv.isConverted()) {deepCopy.add(pv);}else {String propertyName = pv.getName(); // 属性名 age nameObject originalValue = https://tazarkount.com/read/pv.getValue(); // 属性值if (originalValue == AutowiredPropertyMarker.INSTANCE) {Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();if (writeMethod == null) {throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);}originalValue = https://tazarkount.com/read/new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);}Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);Object convertedValue = resolvedValue;boolean convertible = bw.isWritableProperty(propertyName) &&!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);if (convertible) {// 属性值转换convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);}if (resolvedValue == originalValue) {if (convertible) {pv.setConvertedValue(convertedValue);}deepCopy.add(pv);}else if (convertible && originalValue instanceof TypedStringValue &&!((TypedStringValue) originalValue).isDynamic() &&!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {// 转换之后的值赋进去pv.setConvertedValue(convertedValue);deepCopy.add(pv);}else {resolveNecessary = true;deepCopy.add(new PropertyValue(pv, convertedValue));}} } if (mpvs != null && !resolveNecessary) {mpvs.setConverted(); } try {bw.setPropertyValues(new MutablePropertyValues(deepCopy)); } catch (BeansException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Error setting property values", ex); }} 初始化Beanbean 中有一个init-method 的属性 , 这个属性的作用是在 bean 实例化前调用init-method 指定的方法来根据用户业务进行相应的实例化 。我们现在就已经进入 这个方法了 , 首先看一下这个方法的执行位置 , Spring 中程序已经执行过 bean 的实例化 , 并且 进行了属性的填充 , 而就在这时将会调用用户设定的初始化方法 。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction 注册 DisposableBeanSpring 中不但提供了对于初始化方法的扩展入口 , 同样也提供了销毁方法的扩展入口 , 对 于销毁方法的扩展 , 除了我们熟知的配置属性 destroy-method方法外 , 用户还可以注册后处理 器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法 , 代码如下:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {if (mbd.isSingleton()) {// 单例模式下注册需要销毁的bean// 记录到// private final Map disposableBeans = new LinkedHashMap<>();registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));}else {// 自定义的scopeScope scope = this.scopes.get(mbd.getScope());if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");}scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, acc));} }} 4.关于Spring Bean的创建流程总结 - Spring所管理的Bean实际上是缓存在一个ConcurrentHashMap中的(singletonObjects对象中) 。
- 该对象本质上是一个key-value对的形式 , key指的是bean的名字(id) , value是一个Object对象 , 就是所创建的bean对象 。
- 在创建Bean之前 , 首先需要将该Bean的创建标识制定好 , 表示该Bean已经或是即将被创建 , 目的是增强缓存的效率 。
- 根据bean的scope属性来确定当前这个bean是一个singleton还是一个prototype的bean , 然后创建相应的对象 。
- 无论是singleton还是prototype的bean , 其创建的过程是一致的 。
- 通过Java反射机制来创建Bean的实例 , 在创建之前需要检查构造方法的访问修饰符 , 如果不是public的 , 则会调用setAccessible(true) 方法来突破Java的语法限制 , 使得可以通过非public构造方法来完成对象实例的创建 。
- 当对象创建完毕后 , 开始进行对象属性的注入 。
- 在对象属性注入的过程中 , Spring除了去使用之前通过BeanDefinition对象获取的Bean信息外 , 还会通过反射的方式获取到上面所创建的Bean中的真实属性信息(还包括一个class属性 , 表示该Bean所对应的class类型) 。
- 完成Bean属性的注入(或者抛出异常)
- 如果Bean是一个单例的 , 那么将所创建出来的Bean添加到singletonObjects对象中(缓存中) , 供程序后续再次使用 。
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
