Spring GetBean

概述

通过拜读源码,理解其bean的生成原理,并且深刻理解了各个拓展点的功能和实现方式,本文主要解决了如下问题:

  • 框架的结构设计原则

  • bean生成的流程

  • 有哪些拓展点

  • 这些拓展点是如何集成在框架中的,具体原理和使用方法是怎样的

  • 如此多的拓展点有何区别

框架结构分析

Spring GetBean_第1张图片

类图解析

作者将实现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

框架拓展点&与ApplicationContext的区别

容器有哪些功能可以?如上描述,很明显只需要研究ConfigurableBeanFactory接口即可:

registerScope

时机:容器初始化之后的最后一道工序,实例化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");
                }
            }
        }
    }

FactoryBean

时机: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,只有加上“&”才能取得自身的引用

BeanFactoryPostProcessor

时机:容器初始化之后的最后一道工序,实例化bean之前

拓展对象:BeanFactory中满足要求的所有beanDefinition

拓展目的:实例化之前我们往往需要修改读入的beanDefinition或者我们需要为beanFactory增加新的scope、propertyEditor等方法。最主要的有系统提供的PropertyPlaceHolderConfigurer、PropertyOverrideConfigurer和留给用户拓展的CustomEditorConfigurer<结合BeanWrapper理解>、CustomScopeConfigurer;

前者通过修改beanDefinition来实现即时的修改,而后者通过将信息注册给容器的方式来实现后期的功能.

实例演示:TODO

ApplicationContext的优化点:TODO

BeanPostProcessor

Aware 

InitializingBean

DisposableBean 

InstantiationAwareBeanPostProcessor

时机:从字面上理解是在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);
    }

框架执行过程

  1. 规格化传入的beanName参数,因为可能是alias或者带有&

  2. getBean()一开始就检查单例容器中是否存在指定的bean实例,因为原型总是要实例的,找不着也没多大意义

  3. 根据beanName合并beanDefinition,因为bean是存在继承关系的

  4. 初始化该bean所依赖的其他bean

  5. 至此开始走CreatBean的流程了,首先检查有没有需要做替换的方法,并做相应的替换处理

  6. 其次判断有没有实现InstantiationAwareBeanPostProcessor,通过自定义的实例化方法,以便生成代理类

  7. 最后生成bean的实例,并包装成BeanWraper,将customediter拷贝到BeanWraper中,为后续的解析转化做好准备

  8. 判断有没有实现InstantiationAwareBeanPostProcessor,调用其postProcessPropertyValues方法实现自动注解的功能,生成pvs,为第9步服务

  9. 通过BeanWraper利用反射的原理为bean设置属性

  10. 调用一组回调接口,顺序分别是:beanNameAware,beanClassLoaderAware,beanFactoryAware,beanPostProcessor.before,init method,beanPostProcessor.after,destroy method

  11. 根据生成的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;
    }


你可能感兴趣的:(spring,bean,IOC)