通过拜读源码,理解其bean的生成原理,并且深刻理解了各个拓展点的功能和实现方式,本文主要解决了如下问题:
框架的结构设计原则
bean生成的流程
有哪些拓展点
这些拓展点是如何集成在框架中的,具体原理和使用方法是怎样的
如此多的拓展点有何区别
作者将实现BeanFactory的功能划分为上面若干模块,下面是我对于作者如此划分的一些理解(主要是接口分析,类的分析见第四部分的源码解析)
BeanFactory定义了对于bean的一些基本操作,暴露给外界使用,一般使用向上转型的方法
BeanFactory有三个子接口,三个接口各司其职
AutoWireCapableBeanFactory主要负责装配bean,它定义了工厂的行为,根据提供给的context组装bean,通过分析其接口方法,归纳有五大类:
(1)applyBeanPostProcessorsAfterInitialization,applyBeanPostProcessorsBeforeInitialization,applyBeanPropertyValues
(2)autowire
(3)createBean
(4)initializeBean
(5)resolveDependency
ListableBeanFactory主要负责可枚举,可列表的bean,说白了就是可配置,可管理所有的bean,具体的方法有:getBeanDefinitionNames,getBeanNamesForType等
ConfigurableBeanFactory关键在"config",即配置的意思,意为环境;意为拓展的容器,意为为装配而服务。从其接口方法来理解,归纳有下面5大类:
(1)addBeanPostProcessor,addPropertyEditorRegistrar
(2)destroyBean,destroyScopedBean,destroySingletons
(3)getMergedBeanDefinition
(4)registerAlias,registerCustomEditor,registerScope
(5)setParentBeanFactory
容器有哪些功能可以?如上描述,很明显只需要研究ConfigurableBeanFactory接口即可:
时机:容器初始化之后的最后一道工序,实例化bean之前
拓展对象:BeanFactory
拓展目的:我们可以自定义scope,首先需要实现Scope接口,其次就是注册到BeanFactory容器,有两种方法可以实现注册
实例演示:
//直接调用registerScope()方法实现注册 Scope myScope = new MyScope(); beanFactory.registerScope("myScope",myScope);
【CustomScopeConfigure】 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { if (this.scopes != null) { for (Iterator it = this.scopes.entrySet().iterator(); it.hasNext();) { Map.Entry entry = (Map.Entry) it.next(); Object key = entry.getKey(); if (!(key instanceof String)) { throw new IllegalArgumentException( "Invalid scope key [" + key + "]: only Strings allowed"); } String scopeName = (String) key; Object value = entry.getValue(); if (value instanceof Scope) { beanFactory.registerScope(scopeName, (Scope) value); } else if (value instanceof Class) { Class scopeClass = (Class) value; Assert.isAssignable(Scope.class, scopeClass); beanFactory.registerScope(scopeName, (Scope) BeanUtils.instantiateClass(scopeClass)); } else if (value instanceof String) { Class scopeClass = ClassUtils.resolveClassName((String) value, this.beanClassLoader); Assert.isAssignable(Scope.class, scopeClass); beanFactory.registerScope(scopeName, (Scope) BeanUtils.instantiateClass(scopeClass)); } else { throw new IllegalArgumentException("Mapped value [" + value + "] for scope key [" + key + "] is not an instance of required type [" + Scope.class.getName() + "] or a corresponding Class or String value indicating a Scope implementation"); } } } }
时机:Bean生成的最后一道工序:getObjectForBeanInstance
拓展对象:Bean
拓展目的:就像bean中如果需要使用service框架管理的service实例的时候,在webx2的时候便是使用了这种方式的拓展。
实例演示:
public class testFactoryBean implements FactoryBean { public Object getObject() throw Exception { return serviceManager.getService("formService"); } }
而XML的配置就和普通的bean一样配置,不过需要了解的是如果beanName不加“&”,取的是getObject获得的bean,只有加上“&”才能取得自身的引用
时机:容器初始化之后的最后一道工序,实例化bean之前
拓展对象:BeanFactory中满足要求的所有beanDefinition
拓展目的:实例化之前我们往往需要修改读入的beanDefinition或者我们需要为beanFactory增加新的scope、propertyEditor等方法。最主要的有系统提供的PropertyPlaceHolderConfigurer、PropertyOverrideConfigurer和留给用户拓展的CustomEditorConfigurer<结合BeanWrapper理解>、CustomScopeConfigurer;
前者通过修改beanDefinition来实现即时的修改,而后者通过将信息注册给容器的方式来实现后期的功能.
实例演示:TODO
ApplicationContext的优化点:TODO
时机:从字面上理解是在bean的实例化的前后,但是代码中体现出来的我总结有三点,该接口共有三个方法,分别引用在bean的实例前,实例后和setter前。
拓展对象:Bean
拓展目的:目的有两点:<1>自定义bean的实例化方式,比如实现代理;<2>实现注解自动注入的功能,就是说在setter前根据注解生成pvs属性
实例演示:
//对应于上面的拓展目的1,当生成了bean之后变直接结束bean的生成周期,后面的事情便都不做了 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null); } return bean; }
//对应于上面的拓展目的2,在注入属性的时候,实现了其注解自动注入的功能,生成pavs,最后调用apply方法实现setter注入 protected void populateBean(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { 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. boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) { BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } 。。。。。。 boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw); if (hasInstAwareBpps) { for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext(); ) { BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next(); if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } applyPropertyValues(beanName, mbd, bw, pvs); }
规格化传入的beanName参数,因为可能是alias或者带有&
getBean()一开始就检查单例容器中是否存在指定的bean实例,因为原型总是要实例的,找不着也没多大意义
根据beanName合并beanDefinition,因为bean是存在继承关系的
初始化该bean所依赖的其他bean
至此开始走CreatBean的流程了,首先检查有没有需要做替换的方法,并做相应的替换处理
其次判断有没有实现InstantiationAwareBeanPostProcessor,通过自定义的实例化方法,以便生成代理类
最后生成bean的实例,并包装成BeanWraper,将customediter拷贝到BeanWraper中,为后续的解析转化做好准备
判断有没有实现InstantiationAwareBeanPostProcessor,调用其postProcessPropertyValues方法实现自动注解的功能,生成pvs,为第9步服务
通过BeanWraper利用反射的原理为bean设置属性
调用一组回调接口,顺序分别是:beanNameAware,beanClassLoaderAware,beanFactoryAware,beanPostProcessor.before,init method,beanPostProcessor.after,destroy method
根据生成的bean获取客户端所需要的bean,主要是对factorybean的特殊处理
【AbstractBeanFactory】 protected Object doGetBean( final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //将传入的beanName转化为标准的name,例如去除&或者转化alias final String beanName = transformedBeanName(name); Object bean = null; // 先从singleton对象中查找。 Object sharedInstance = getSingleton(beanName); if (sharedInstance != 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获取客户端所需要的bean,后面有解析 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { //检查该bean是否处于创建阶段,防止循环引用 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //检查父工厂是否存在,若当前工厂不存在该name,则委托父工厂完成getBean的操作 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (args != null) { return parentBeanFactory.getBean(nameToLookup, args); } else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } //如果不进行类型检查,标记该name为已创建 if (!typeCheckOnly) { markBeanAsCreated(beanName); } //合并beanDefinition,主要是针对内部bean和有parent的bean做的合并处理 //当beanName不同的时候,用子bean的definition覆盖父bean //当beanName发生相同的时候,说明在一个bean配置文件是不可能的,因此从父beanFactory中寻找父bean进行合并 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //初始化该bean所依赖的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (int i = 0; i < dependsOn.length; i++) { String dependsOnBean = dependsOn[i]; getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // 开始创建bean实例,后面有解析 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //非单例bean的创建 else if (mbd.isPrototype()) { // It's a prototype -> create a new instance. Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); final Scope 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() { 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); } } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return bean; }
【AbstractAutowireCapableBeanFactory】 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; //生成包装类BeanWrapper,该类实现了ProperyEditer可以对string类型的变量进行转换,不过这里把自定义的customediter拷贝进来了 //为什么就不能另外搞一个组件完成这一工作呢? if (mbd.isSingleton()) { instanceWrapper = (BeanWrapper) this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // 允许对合并后的属性做修改 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } //及早暴露单例bean的引用,从而允许setter注入方式的循环引用 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isDebugEnabled()) { logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, new ObjectFactory() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //设置bean的property //从beanDefinition取得properties values //调用postProcessAfterInstantiation方法 //依赖检查 //使properties values生效 populateBean(beanName, mbd, instanceWrapper); //一组回调接口 //实现了beanNameAware的bean设置beanName //实现了beanClassLoaderAware的bean设置beanClassLoader //实现了beanFactoryAware的bean设置beanFactory //调用beanPostProcessor的before方法 //invoke init method,其实可以用init-method来代替,因为这样做侵入性就较低了 //调用beanPostProcessor的after方法 exposedObject = initializeBean(beanName, exposedObject, mbd); } ...... // 注册销毁的回调方法,不如采用destroy-method,和上面的init一样,这样做使得侵入性变低了 registerDisposableBeanIfNecessary(beanName, bean, mbd); return exposedObject; }