BeanPostProcessor里的实例化前后指的是调用init(init-method)方法前后,这时实际上bean已经开始了实例化(详细的可以参考类的实例化全过程),这时取到的仅仅是某一指定类的实例。即使进行修改也只是修改当前这一实例,而无法对bean的元数据修改。
由于postProcessor可能会在bean的实例化之前进行调用,所以在实例化前context肯定需要先拿到postProcessor,这也就可以解释上面的代码中在解析完配置文件后就开始注册BeanFactoryPostProcessor和BeanPostProcessor。
listener//tood
具体的关于postProcessor和Listener相关会在将整体流程理顺后再详细介绍。
finishBeanFactoryInitialization(ConfigurableListableBeanFactory) protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } beanFactory.setTempClassLoader(null); //缓存bean定义 beanFactory.freezeConfiguration(); beanFactory.preInstantiateSingletons(); } 方法首先查找是否开启了注册conversionService,conversionService是用于进行两个类转换的,例如之前说过了Environment类就依赖该实例将定义的变量转换为相应的类型。 如果要开启注册conversionService,可以在配置文件中配置。```
preInstantiateSingletons通过一个for循环来实例化所有注册到容器中的bean定义所代表的的bean。
在确定好每一个beanName所代表的的bean确实需要实例化后首先检查当前beanName是否实现了接口
而由于```FactoryBean```本身首先是一个bean,所以我们也可以在ioc容器中获取该bean的实例。如果我们通过getBean(beanName)方法获取的实际上是```FactoryBean```产生的实例类型,想要获取```FactoryBean```的实例需要使用```getBean("&" + beanName)```。 #### getBean(String) getBean是一个重载方法,主要还是调用doGetBean()方法实现功能。 protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //取该beanName在容器中保存的name //比如上面介绍的factoryBean会加一个& 以及给bean配置的别名等 final String beanName = transformedBeanName(name); Object bean; //尝试从保存bean的容器中取,如果已经存在则不用再次实例化 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); }else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }else { //对于非单例bean 如果该bean正在被创建而又尝试再次创建则会直接抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { //!containsBeanDefinition(beanName)表示从当前容器中没有找到匹配的BeanDefinition 尝试从父容器中查找 String nameToLookup = originalBeanName(name); if (args != null) { return (T) parentBeanFactory.getBean(nameToLookup, args); }else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } if (!typeCheckOnly) { //标记当前beanName所表示的bean正在被创建或已经被创建 markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //这一步根据其实现貌似主要是检查当前BeanDefinition表示的bean是否是一个抽象类,但是前面已经检查过了 这里再次检查貌似意义不大 checkMergedBeanDefinition(mbd, beanName, args); //检查是否配置了bean的依赖 如果存在则需要先实例化被依赖的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dependsOnBean : dependsOn) { if (isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } registerDependentBean(dependsOnBean, beanName); getBean(dependsOnBean); } } if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }else if (mbd.isPrototype()) { Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } 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 '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { 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; } } if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { try { return getTypeConverter().convertIfNecessary(bean, requiredType); }catch (TypeMismatchException ex) { if (logger.isDebugEnabled()) { logger.debug("Failed to convert bean '" + name + "' to required type [" + ClassUtils.getQualifiedName(requiredType) + "]", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; } 方法中的try-catch块用于创建bean实例,代码很多,不过只是根据bean的作用范围来进行创建如Singleton,prototype或者session等。创建bean的过程大同小异,区别仅在与实例保存的地方。单例bean被保存在一个map中,整个程序运行期间有效。原型bean保存在另外的容器中,每一次使用时需要重新创建。 以单例bean创建过程为例,主要实现过程都在```getSingleton(...)```方法中了。```getSingleton(...)```的主要功能就是检查bean是否已经创建,如果没创建就进行创建然后保存到容器中。创建bean的过程由一个匿名内部类实现。 #### createBean(String beanName, RootBeanDefinition mbd, Object[] args) protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { resolveBeanClass(mbd, beanName); try { mbd.prepareMethodOverrides(); }catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //首先尝试执行BeanPostProcessor,如果存在后置处理器 那么首先实例化bean执行处理器 Object bean = resolveBeforeInstantiation(beanName, mbd); if (bean != null) { return bean; } }catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } //不存在后置处理器或者存在的执行处理器过程创建实例失败或没有创建实例的动作则执行下面的方法 Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } 上面方法中有这样一句```mbd.prepareMethodOverrides()```。```methodOverrides```实际上市BeanDefinition中的一个属性。其主要用于记录在配置文件中lookup-method和replaced-method参数设置的值。详情可以看这里:[methodOverrides](https://blog.csdn.net/G0_hw/article/details/82149000) #### doCreateBean(...) protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { //如果已经实例化需要重新实例化则从缓存中删除 重新设置 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } //more code } 方法开头显示创建了一个BeanWrapper的对象,BeanWrapper相当于一个代理器,Spring委托BeanWrapper来完成bean内部属性的初始化。 上述方法代码很多,在创建阶段只需要关注前几行。如果该bean的实例未被创建则直接创建一个。创建的方法有createBeanInstance完成。 #### createBeanInstance(...) protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { Class<?> beanClass = resolveBeanClass(mbd, beanName); //判断当前bean类是否被定义为public 非public的类无法在其他类中实例化 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()); } 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() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } return instantiateBean(beanName, mbd); } 该方法先是尝试查看是否配置了工厂方法,如果存在工厂方法则由工厂方法进行创建。 接下来的几行代码是用来提升性能的。spring在创建实例后会将创建该实例的constructor方法缓存,这样下一次需要创建该bean时直接取出构造方法创建即可不需要再重新解析一次。 如果没有工厂方法并且构造方法也没有缓存,同时没有找到有参的构造函数,那么会通过放射调用类的默认无参构造函数。 #### instantiateBean(String, RootBeanDefinition) 该实例化方法没有太多解析的必要,基本就是通过反射的原理获取无参构造函数,通过构造函数来实例化类。 ### DI 到这里为止创建一个实例的过程就完成了,接下来就是检查该实例是否需要被注入其他的属性了。 #### 回到doCreateBean(...) 前面在创建bean实例时调用到了doCreateBean(...)方法,在创建好实例后的后续功能也依赖于该方法。 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // other-code Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 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); } } // other-code return exposedObject; } 在DI阶段我们需要关注的就上上面的代码,首先是通过populateBean方法对在配置文件中配置的property属性进行设置值。 populateBean顾名思义就是对bean中的属性添加数据。populateBean中其实是通过后置处理器来进行属性的设置,主要的代码如下: