• 6.2.3-Bean的加载处理


    AbstractBeanFactory中doGetBean方法中始终调用了getObjectForBeanInstance方法,这个方法是对参数进行过滤;

      1     @SuppressWarnings("unchecked")
      2     protected <T> T doGetBean(
      3             final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
      4             throws BeansException {
      5 
      6         final String beanName = transformedBeanName(name);
      7         Object bean;
      8 
      9         // Eagerly check singleton cache for manually registered singletons.
     10         Object sharedInstance = getSingleton(beanName);
     11         if (sharedInstance != null && args == null) {
     12             if (logger.isDebugEnabled()) {
     13                 if (isSingletonCurrentlyInCreation(beanName)) {
     14                     logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
     15                             "' that is not fully initialized yet - a consequence of a circular reference");
     16                 }
     17                 else {
     18                     logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
     19                 }
     20             }
     21             bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
     22         }
     23 
     24         else {
     25             // Fail if we're already creating this bean instance:
     26             // We're assumably within a circular reference.
     27             if (isPrototypeCurrentlyInCreation(beanName)) {
     28                 throw new BeanCurrentlyInCreationException(beanName);
     29             }
     30 
     31             // Check if bean definition exists in this factory.
     32             BeanFactory parentBeanFactory = getParentBeanFactory();
     33             if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
     34                 // Not found -> check parent.
     35                 String nameToLookup = originalBeanName(name);
     36                 if (args != null) {
     37                     // Delegation to parent with explicit args.
     38                     return (T) parentBeanFactory.getBean(nameToLookup, args);
     39                 }
     40                 else {
     41                     // No args -> delegate to standard getBean method.
     42                     return parentBeanFactory.getBean(nameToLookup, requiredType);
     43                 }
     44             }
     45 
     46             if (!typeCheckOnly) {
     47                 markBeanAsCreated(beanName);
     48             }
     49 
     50             try {
     51                 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
     52                 checkMergedBeanDefinition(mbd, beanName, args);
     53 
     54                 // Guarantee initialization of beans that the current bean depends on.
     55                 String[] dependsOn = mbd.getDependsOn();
     56                 if (dependsOn != null) {
     57                     for (String dependsOnBean : dependsOn) {
     58                         if (isDependent(beanName, dependsOnBean)) {
     59                             throw new BeanCreationException(mbd.getResourceDescription(), beanName,
     60                                     "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
     61                         }
     62                         registerDependentBean(dependsOnBean, beanName);
     63                         getBean(dependsOnBean);
     64                     }
     65                 }
     66 
     67                 // Create bean instance.
     68                 if (mbd.isSingleton()) {
     69                     sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
     70                         @Override
     71                         public Object getObject() throws BeansException {
     72                             try {
     73                                 return createBean(beanName, mbd, args);
     74                             }
     75                             catch (BeansException ex) {
     76                                 // Explicitly remove instance from singleton cache: It might have been put there
     77                                 // eagerly by the creation process, to allow for circular reference resolution.
     78                                 // Also remove any beans that received a temporary reference to the bean.
     79                                 destroySingleton(beanName);
     80                                 throw ex;
     81                             }
     82                         }
     83                     });
     84                     bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
     85                 }
     86 
     87                 else if (mbd.isPrototype()) {
     88                     // It's a prototype -> create a new instance.
     89                     Object prototypeInstance = null;
     90                     try {
     91                         beforePrototypeCreation(beanName);
     92                         prototypeInstance = createBean(beanName, mbd, args);
     93                     }
     94                     finally {
     95                         afterPrototypeCreation(beanName);
     96                     }
     97                     bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
     98                 }
     99 
    100                 else {
    101                     String scopeName = mbd.getScope();
    102                     final Scope scope = this.scopes.get(scopeName);
    103                     if (scope == null) {
    104                         throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
    105                     }
    106                     try {
    107                         Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
    108                             @Override
    109                             public Object getObject() throws BeansException {
    110                                 beforePrototypeCreation(beanName);
    111                                 try {
    112                                     return createBean(beanName, mbd, args);
    113                                 }
    114                                 finally {
    115                                     afterPrototypeCreation(beanName);
    116                                 }
    117                             }
    118                         });
    119                         bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    120                     }
    121                     catch (IllegalStateException ex) {
    122                         throw new BeanCreationException(beanName,
    123                                 "Scope '" + scopeName + "' is not active for the current thread; consider " +
    124                                 "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    125                                 ex);
    126                     }
    127                 }
    128             }
    129             catch (BeansException ex) {
    130                 cleanupAfterBeanCreationFailure(beanName);
    131                 throw ex;
    132             }
    133         }
    134 
    135         // Check if required type matches the type of the actual bean instance.
    136         if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
    137             try {
    138                 return getTypeConverter().convertIfNecessary(bean, requiredType);
    139             }
    140             catch (TypeMismatchException ex) {
    141                 if (logger.isDebugEnabled()) {
    142                     logger.debug("Failed to convert bean '" + name + "' to required type [" +
    143                             ClassUtils.getQualifiedName(requiredType) + "]", ex);
    144                 }
    145                 throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    146             }
    147         }
    148         return (T) bean;
    149     }
    View Code
        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.
            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.
            if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
                return beanInstance;
            }
    
            Object object = null;
            if (mbd == null) {
                object = getCachedObjectForFactoryBean(beanName);
            }
            if (object == null) {
                // Return bean instance from factory.
                FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
                // Caches object obtained from FactoryBean if it is a singleton.
                if (mbd == null && containsBeanDefinition(beanName)) {
                    mbd = getMergedLocalBeanDefinition(beanName);
                }
                boolean synthetic = (mbd != null && mbd.isSynthetic());
                object = getObjectFromFactoryBean(factory, beanName, !synthetic);
            }
            return object;
        }
    View Code

    getObjectForBeanInstance方法;

    getObjectFromFactoryBean;单例时候,确保实例是全局唯一的,主要对缓存的Map进行查询是否已经存在!

        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 {
                                    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;
            }
        }

      doGetObjectFromFactoryBean: 实实在在的实例化

    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 {
                                    return factory.getObject();
                                }
                            }, acc);
                    }
                    catch (PrivilegedActionException pae) {
                        throw pae.getException();
                    }
                }
                else {
                    object = factory.getObject();
                }
            }
            catch (FactoryBeanNotInitializedException ex) {
                throw new BeanCurrentlyInCreationException(beanName, ex.toString());
            }
            catch (Throwable ex) {
                throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
            }
    
            // Do not accept a null value for a FactoryBean that's not fully
            // initialized yet: Many FactoryBeans just return null then.
            if (object == null && isSingletonCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(
                        beanName, "FactoryBean which is currently in creation returned null from getObject");
            }
            return object;
        }

    这个方法其实就做了factory.getObject()

    对以上这几部,

    1.首先对doGetBean()方法中参数的过滤 getObjectForBeanInstance

      主要参数:  Object beanInstance, String name, String beanName, RootBeanDefinition mbd

      对name的过滤,如果name制定要获取FactoryBean本身实例,而beanInstance却又不是FactoryBean,直接抛异常

      2.对beanInstance进行过了,判断不属于FactoryBean 或者

    if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
    return beanInstance;
    }

    对name 进行判断是不是工厂bean,2条有一条就直接返回实例,

    public static boolean isFactoryDereference(String name) {
    return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
    }

    1. 尝试从缓存中获取实例[FactoryBeanRegistrySupport负责]
    2. 准备beanDefinition,委托getObjectFromFactoryBean处理

    单例时保障实例全局唯一,同时也是多例的方法,getObjectFromFactoryBean(factory, beanName, !synthetic);

    1.判断是不是单例,

      1.1   先查缓存,不存在就直接调用doGetObjectFromFactoryBean去实例化一个,

      1.2  由于这样新建就没有机会调用BeanPostProcessor了,所以这边直接调用其postProcessAfterInitialization

    @Override
    protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
    return applyBeanPostProcessorsAfterInitialization(object, beanName);
    }

      1.3 把生产的实例再换成到map中

      

    doGetObjectFromFactoryBean

    就调用了getobject方法

  • 相关阅读:
    从上往下,从左往右
    idea jar包破解
    StarUML 2下载、安装、破解全过程
    windows10 找回windows照片查看器的方法
    Tomcat报错Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
    Java基于SSM在线学习系统设计与实现
    多个iframe,删除详情页时刷新同级iframe的table list
    Eclipse项目工程导入到IDEA继续开发-超详细
    MySQL用B+树做索引
    彻底禁用Chrome插件停用开发者模式提示插件version.dll
  • 原文地址:https://www.cnblogs.com/java-synchronized/p/6801893.html
Copyright © 2020-2023  润新知