• spring IOC之篇五 bean的加载--缓存中获取


    我们终于结束了对XML配置文件的解析,接下来我们要分析bean的加载,即对代码getBean的分析:

    People p = (People)ctx.getBean("cutesource"); 

    @SuppressWarnings("unchecked")
        protected <T> T doGetBean(
                final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
                throws BeansException {
     // 根据名称获取对应的beanName。如果传入的别名A指向bean B则返回bean B的beanName,如果别名A指向别名B 然后别名B指向bean c 则返回bean C,如果传入的是FactoryBean,则则去掉修饰符 ,比如 name=”&aa” 则变为 name=”aa”
            final String beanName = transformedBeanName(name);
            Object bean;
    
            // Eagerly check singleton cache for manually registered singletons.
           // 尝试从缓存中加载单例。首次从单例缓存中加载,如果不成功则从singletonFactories中加载。因为在创建单例的时候存在着循环依赖,所以不等bean创建完成就就将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean依赖上一个bean 则直接使用ObjectFactory
            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最初始化的状态,不一定是最终的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.
           // 只有在单例的情况下面才去解决循环依赖,如果原型的情况下面则直接抛出异常
                if (isPrototypeCurrentlyInCreation(beanName)) {
                    throw new BeanCurrentlyInCreationException(beanName);
                }
    
                // Check if bean definition exists in this factory.
                 
                BeanFactory parentBeanFactory = getParentBeanFactory();
                if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                    // Not found -> check parent.
                   // 如果parentBeanFactory 不为空,且当前的beanFactory不包含beanName则递归到他的上一层去加载beanName
                    String nameToLookup = originalBeanName(name);
                    if (args != null) {
                        // Delegation to parent with explicit args.
                    // args为传入的构造函数的参数
                        return (T) parentBeanFactory.getBean(nameToLookup, args);
                    }
                    else {
                         // 没有构造参数则使用标准的方法获取bean
                        // No args -> delegate to standard getBean method.
                        return parentBeanFactory.getBean(nameToLookup, requiredType);
                    }
                }
    
                if (!typeCheckOnly) {
                    markBeanAsCreated(beanName);
                }
    
                try {
                   // 将GenericBeanDefinition转换为 RootBeanDefinition
                    final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                   // 如果父类bean不为空的话,合并一下父类的属性
                    checkMergedBeanDefinition(mbd, beanName, args);
    
                    // Guarantee initialization of beans that the current bean depends on.
                    String[] dependsOn = mbd.getDependsOn();
                    if (dependsOn != null) {
                   // 获取bean的其他依赖,如果依赖其他的bean,则先获取其他的bean
                        for (String dependsOnBean : dependsOn) {
                            if (isDependent(beanName, dependsOnBean)) {
                                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                        "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
                            }
                // 把该bean依赖的其他的bean加入到dependentBeanMap集合中去
                            registerDependentBean(dependsOnBean, beanName);
      // 获取其依赖的其他bean
                            getBean(dependsOnBean);
                        }
                    }
    
                    // Create bean instance.
         // 根据不同的scope进行初始化策略
                    if (mbd.isSingleton()) {
                        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                            @Override
                            public Object getObject() throws BeansException {
                                try {
                                    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 = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                    }
    
                    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 = this.scopes.get(scopeName);
                        if (scope == null) {
                            throw new IllegalStateException("No Scope registered for scope name '" + 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;
                }
            }
    // 根据传入的参数 requiredType和返回的bean类型不一致的时候,进行装换
            // Check if required type matches the type of the actual bean instance.
            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;
        }

    进一步分析 FactoryBean的使用

    FactoryBean接口对于Spring框架来说占有重要的地位,Spring自身就提供了70多种实现类。他们隐藏了一下实例化的复杂的细节,给上层应用带来便利。

    public interface FactoryBean<T> {
       // 返回由FactoryBean创建的Bean实例,如果isSingleton()方法返回的是true,则该实例会放入到Spring容器的单例缓存池当中
        T getObject() throws Exception;
    
        // 返回FactoryBean创建的bean类型
        Class<?> getObjectType();
       // 返回由factoryBean创建实例的Bean是singleton还是prototype
        boolean isSingleton();
    
    }

    创建一个实体用Factory进行实例化

    public class People {
            private String id;  
            private String name;  
            private Integer age;
            public String getId() {
                return id;
            }

    创建一个自定义的FactoryBean方法

    public class PeopleFactoryBean implements FactoryBean<People> {
    
        private String peopleInfo;
        
        public People getObject() throws Exception {
            
            People people = new People();
            String[] infos = peopleInfo.split(",");
            people.setId(infos[0]);
            people.setName(infos[1]);
            people.setAge(Integer.parseInt(infos[2]));
            return people;
        }
    
        public Class<People> getObjectType() {
            return People.class;
        }
    
        public boolean isSingleton() {
            return false;
        }
    
        public String getPeopleInfo() {
            return peopleInfo;
        }
    
        public void setPeopleInfo(String peopleInfo) {
            this.peopleInfo = peopleInfo;
        }
        
    }

    配置文件中配置:

    <bean id="people" class="com.spring.test.factory.PeopleFactoryBean">
            <property name="peopleInfo" value="gh2,address2,22"></property>
    </bean> 

    即可使用自定义的逻辑进行实例化,当调用getBean的时候,Spring通过反射机制发现PeopleFactoryBean实现了FactoryBean,这时候Spring容器就调用接口方法PeopleFactoryBean#getObject()方法返回。如果希望获取PeopleFactoryBean实例,则在beanName前面显示的加&

    解下来对从单列缓存池获取对象进行分析:

    Object sharedInstance = getSingleton(beanName)

    代码如下:

    // 参数allowEarlyReference 设置为true,则表示允许早期依赖
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
            // 先从spring单列缓存池获取对象
            Object singletonObject = this.singletonObjects.get(beanName);
            if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
               // 如果单列缓存池为空,则锁定全局变量进行处理
                synchronized (this.singletonObjects) {
                    // earlySingletonObjects存放的是允许早期依赖的实例化的半成品,此时表示此bean正在加载,如果正在加载则不予处理
                    singletonObject = this.earlySingletonObjects.get(beanName);
                    if (singletonObject == null && allowEarlyReference) {
                        // 当某些方法需要初始化的时候,需要调用addSingletonFactory方法将对应的ObejctFactory初始化策略存储在singletonFactories,获取存放的singletonFactory
                        ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                        if (singletonFactory != null) {
                            // 如果singletonFactory不为空,使用singletonFactory的初始化方法进行初始化
                            singletonObject = singletonFactory.getObject();
                            // earlySingletonObjects和singletonFactories互斥,如果earlySingletonObjects包含此bean,则singletonFactories中就不会存在此bean的初始化方法
                            this.earlySingletonObjects.put(beanName, singletonObject);
                            this.singletonFactories.remove(beanName);
                        }
                    }
                }
            }
            return (singletonObject != NULL_OBJECT ? singletonObject : null);
        }

    getBean()方法中

    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);是一个高频率使用的方法,其目的是用于检测当前bean是否是FactoryBean类型的bean,如果是那么需要调用bean对应的FactoryBean实例中的getObject()作为返回值。

    protected Object getObjectForBeanInstance(
                Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
    
            // Don't let calling code try to dereference the factory if the bean isn't a factory.
           // 如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型的则检测不通过
            if (BeanFactoryUtils.isFactoryDereference(name) && !(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.
     // 如果传入了beanName加了前缀&,则直接返回工厂而不是返回工程对应的getObejct()方法的返回值
            if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
                return beanInstance;
            }
    
            Object object = null;
            if (mbd == null) {
                // 到了这里,可以肯定此时的bean肯定是FactoryBean,从缓存中获取bean
                object = getCachedObjectForFactoryBean(beanName);
            }
            if (object == null) {
                // Return bean instance from factory.
          // 到了这里,可以肯定此时的bean肯定是FactoryBean,所以强制转换
                FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
                // Caches object obtained from FactoryBean if it is a singleton.
                if (mbd == null && containsBeanDefinition(beanName)) {
                 // 将GenericBeanDefinition转换为RootBeanDefinition,如果指定的BeanName是子Bean的话,则同时合并父类的属性
                    mbd = getMergedLocalBeanDefinition(beanName);
                }
               // 是否是用户自定义而不是程序本身定义,在AOP时候,是用户自定义,此时是程序本身定义的
                boolean synthetic = (mbd != null && mbd.isSynthetic());
             // 获取bean
                object = getObjectFromFactoryBean(factory, beanName, !synthetic);
            }
            return object;
        }
    
    继续进一步进行代码的分析
    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
            if (factory.isSingleton() && containsSingleton(beanName)) {
             // 如果单例对象,则加入了缓存的处理
                synchronized (getSingletonMutex()) {
                    Object object = this.factoryBeanObjectCache.get(beanName);
                    if (object == null) {
                        object = doGetObjectFromFactoryBean(factory, beanName);
                        // Only post-process and store if not put there already during getObject() call above
                        // (e.g. because of circular reference processing triggered by custom getBean calls)
                        Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                        if (alreadyThere != null) {
                            object = alreadyThere;
                        }
                        else {
                            if (object != null && shouldPostProcess) {
                                try {
                               // 获取完单例对象以后,并没有直接返回,而是调用了后处理器,在所有的bean初始化后都调用BeanPostProcessor的postProcessAfterInitialization方法进行处理
                                    object = postProcessObjectFromFactoryBean(object, beanName);
                                }
                                catch (Throwable ex) {
                                    throw new BeanCreationException(beanName,
                                            "Post-processing of FactoryBean's singleton object failed", ex);
                                }
                            }
                            this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
                        }
                    }
                    return (object != NULL_OBJECT ? object : null);
                }
            }
            else {
               // 如果是非单例对象,则不用缓存
                Object object = doGetObjectFromFactoryBean(factory, beanName);
                if (object != null && shouldPostProcess) {
                    try {
                        object = postProcessObjectFromFactoryBean(object, beanName);
                    }
                    catch (Throwable ex) {
                        throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
                    }
                }
                return object;
            }
        }

    进一步分析代码

    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(new PrivilegedExceptionAction<Object>() {
                            @Override
                            public Object run() throws Exception {
                           // 返回FactoryBean对应的实例 getObejct()方法
                                    return factory.getObject();
                                }
                            }, acc);
                    }
                    catch (PrivilegedActionException pae) {
                        throw pae.getException();
                    }
                }
                else {
                    object = factory.getObject();
                }
            }
  • 相关阅读:
    Python迭代器的反复使用
    快速求幂模运算实现
    rural lifestyle & city lifestyle
    Python实现 扩展的欧几里德算法求(模逆数)最大公约数
    jupyter themes一行命令设置个人最爱界面
    python数组、矩阵相乘的多种方式
    有一组整型数,其中除了2个数字以外的其它数字都是俩俩成对出现的,编写程序找出这2个不成对出现的数字。
    Linux线程池技术处理多任务
    编写函数求两个整数 a 和 b 之间的较大值。要求不能使用if, while, switch, for, ?: 以 及任何的比较语句。
    C++const类型的引用参数
  • 原文地址:https://www.cnblogs.com/histlyb/p/8988808.html
Copyright © 2020-2023  润新知