spring-beans關鍵類圖結構

1、spring-beans相關類圖結構java

在4.x中spring對XmlBeanFactory設置爲已過期的類。可是在咱們解讀源代碼的時候並不影響,過期並不表示不可以使用。spring

下面對接口進行解讀express

一、AliasRegistry接口json

接口定義的方法以下:(源代碼)緩存

public interface AliasRegistry {
    void registerAlias(String var1, String var2);

    void removeAlias(String var1);

    boolean isAlias(String var1);

    String[] getAliases(String var1);
}

接口主要的做用:安全

  1. registerAlias對別名bean的註冊。
  2. removeAlias 移除別名bean
  3. isAlias 判斷一個bean是不是一個別名bean
  4. getAliases 獲取一個bean的別名

這裏解釋一下什麼叫別名bean,在spring註冊的時候默認會根據id做爲一個bean的名稱(放入到beanFactory容器中)若是在定義的時候爲指定id那麼默認系統會根據一系列的命名規則生成beanName併發

例如在applicationContext.xml文件中若是設置了app

<bean name="myBean,gagBean" class="com.wolf.bean.Mybean1">
    <property name="name">
        <value>鄭先生</value>
    </property>
    <property name="pwd">
        <value>666666888888</value>
    </property>
</bean>

那麼name元素中的myBean,gagBean就是兩個別名ide

二、SimpleAliasRegistry 簡單別名註冊類(這裏實現了AliasRegistry接口,並實現了接口中的方法)post

public class SimpleAliasRegistry implements AliasRegistry {
    //這裏必定了一個一個線程安全的map,在map中key爲beanName名稱,而value就是alias別名
    private final Map<String, String> aliasMap = new ConcurrentHashMap(16);

    public SimpleAliasRegistry() {
    }
    //實現了AliasRegistry 接口registerAlias的方法(完成了別名註冊)
    public void registerAlias(String name, String alias) {
        Assert.hasText(name, "\'name\' must not be empty");
        Assert.hasText(alias, "\'alias\' must not be empty");
        //這裏判斷當前別名和beanName是否相同,若是相同則移除別名
        if(alias.equals(name)) {
            this.aliasMap.remove(alias);
        } else {
            String registeredName = (String)this.aliasMap.get(alias);
            if(registeredName != null) {
                if(registeredName.equals(name)) {
                    return;
                }

                if(!this.allowAliasOverriding()) {
                    throw new IllegalStateException("Cannot register alias \'" + alias + "\' for name \'" + name + "\': It is already registered for name \'" + registeredName + "\'.");
                }
            }

            this.checkForAliasCircle(name, alias);
            this.aliasMap.put(alias, name);
        }

    }

    protected boolean allowAliasOverriding() {
        return true;
    }
    //判斷是否有一個別名
    public boolean hasAlias(String name, String alias) {
        Iterator var3 = this.aliasMap.entrySet().iterator();

        Entry entry;
        String registeredName;
        do {
            if(!var3.hasNext()) {
                return false;
            }

            entry = (Entry)var3.next();
            registeredName = (String)entry.getValue();
        } while(!registeredName.equals(name));

        String registeredAlias = (String)entry.getKey();
        return registeredAlias.equals(alias) || this.hasAlias(registeredAlias, alias);
    }
    //移除一個別名
    public void removeAlias(String alias) {
        String name = (String)this.aliasMap.remove(alias);
        if(name == null) {
            throw new IllegalStateException("No alias \'" + alias + "\' registered");
        }
    }
    //判斷beanName是否存在別名
    public boolean isAlias(String name) {
        return this.aliasMap.containsKey(name);
    }
    //獲取一個beanName全部的別名。這裏使用synchronized來實現了線程安全,經過ArrayList將多個別名組裝起來
    public String[] getAliases(String name) {
        ArrayList result = new ArrayList();
        Map var3 = this.aliasMap;
        synchronized(this.aliasMap) {
            this.retrieveAliases(name, result);
        }

        return StringUtils.toStringArray(result);
    }

    private void retrieveAliases(String name, List<String> result) {
        Iterator var3 = this.aliasMap.entrySet().iterator();

        while(var3.hasNext()) {
            Entry entry = (Entry)var3.next();
            String registeredName = (String)entry.getValue();
            if(registeredName.equals(name)) {
                String alias = (String)entry.getKey();
                result.add(alias);
                this.retrieveAliases(alias, result);
            }
        }

    }

    public void resolveAliases(StringValueResolver valueResolver) {
        Assert.notNull(valueResolver, "StringValueResolver must not be null");
        Map var2 = this.aliasMap;
        synchronized(this.aliasMap) {
            HashMap aliasCopy = new HashMap(this.aliasMap);
            Iterator var4 = aliasCopy.keySet().iterator();

            while(var4.hasNext()) {
                String alias = (String)var4.next();
                String registeredName = (String)aliasCopy.get(alias);
                String resolvedAlias = valueResolver.resolveStringValue(alias);
                String resolvedName = valueResolver.resolveStringValue(registeredName);
                if(resolvedAlias != null && resolvedName != null && !resolvedAlias.equals(resolvedName)) {
                    if(!resolvedAlias.equals(alias)) {
                        String existingName = (String)this.aliasMap.get(resolvedAlias);
                        if(existingName != null) {
                            if(!existingName.equals(resolvedName)) {
                                throw new IllegalStateException("Cannot register resolved alias \'" + resolvedAlias + "\' (original: \'" + alias + "\') for name \'" + resolvedName + "\': It is already registered for name \'" + registeredName + "\'.");
                            }

                            this.aliasMap.remove(alias);
                            break;
                        }

                        this.checkForAliasCircle(resolvedName, resolvedAlias);
                        this.aliasMap.remove(alias);
                        this.aliasMap.put(resolvedAlias, resolvedName);
                    } else if(!registeredName.equals(resolvedName)) {
                        this.aliasMap.put(alias, resolvedName);
                    }
                } else {
                    this.aliasMap.remove(alias);
                }
            }

        }
    }

    protected void checkForAliasCircle(String name, String alias) {
        if(this.hasAlias(alias, name)) {
            throw new IllegalStateException("Cannot register alias \'" + alias + "\' for name \'" + name + "\': Circular reference - \'" + name + "\' is a direct or indirect alias for \'" + alias + "\' already");
        }
    }

    public String canonicalName(String name) {
        String canonicalName = name;

        String resolvedName;
        do {
            resolvedName = (String)this.aliasMap.get(canonicalName);
            if(resolvedName != null) {
                canonicalName = resolvedName;
            }
        } while(resolvedName != null);

        return canonicalName;
    }
}

三、BeanDefinitionRegistry  bean定義註冊接口(註冊類)

public interface BeanDefinitionRegistry extends AliasRegistry {
    //往註冊表註冊一個新的BeanDefinition實例
    void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
	//移除指定的BeanDefinition
    void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
    //獲取指定的BeanDefinition信息
    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
	//判斷BeanDefinition在註冊表中是否註冊過
    boolean containsBeanDefinition(String var1);
	//獲取註冊表中BeanDefinition全部的beanNames信息(arrays)
    String[] getBeanDefinitionNames();
	//獲取註冊表中BeanDefinition註冊的數量
    int getBeanDefinitionCount();
    //判斷一個beanName是否被使用
    boolean isBeanNameInUse(String var1);
}
//這裏咱們留下一個思考:在實際的實現中?spring用什麼存在BeanDefinition實例信息。
//DefaultListableBeanFactory實現了BeanDefinitionRegistry 接口。當咱們分析DefaultListableBeanFactory實現的時候再來具體分析

四、SingletonBeanRegistry 單例bean註冊接口(註冊類)

public interface SingletonBeanRegistry {
    //註冊一個單例bean
    void registerSingleton(String var1, Object var2);
	//根據beanName獲取一個單例bean
    Object getSingleton(String var1);
	//判斷是否包含單例bean
    boolean containsSingleton(String var1);
	//獲取此註冊表中全部的單例beanName(arrays)
    String[] getSingletonNames();
	//返回此註冊表中註冊的單例bean的數目 
    int getSingletonCount();
    //返回此註冊表所使用的單例互斥(用於外部合做者)。 
    Object getSingletonMutex();
}

五、DefaultSingletonBeanRegistry 默認單例bean註冊(extends SimpleAliasRegistry implements SingletonBeanRegistry)

繼承了SimpleAliasRegistry簡單bean註冊,實現了單例bean註冊接口

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    //null單例對象的內部標記:用做併發映射的標記值(不支持null值)。 
    protected static final Object NULL_OBJECT = new Object();
    protected final Log logger = LogFactory.getLog(this.getClass());
	//採用線程安全的map實現來存在單例bean key爲beanName,value爲單例bean對象
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
	//單例工廠集合
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
	//early單例對象集合
    private final Map<String, Object> earlySingletonObjects = new HashMap(16);
	//註冊的單例集合
    private final Set<String> registeredSingletons = new LinkedHashSet(256);
    private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap(16));
    private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap(16));
    private Set<Exception> suppressedExceptions;
    private boolean singletonsCurrentlyInDestruction = false;
    private final Map<String, Object> disposableBeans = new LinkedHashMap();
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap(16);
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap(64);
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap(64);

    public DefaultSingletonBeanRegistry() {
    }

	//單例bean註冊#操做很簡單,首先根據beanName在map中獲取若是不存在就直接新增,不然提示異常【不能註冊這個單例bean,由於這個beanName已經被其餘單例bean註冊了】
    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        Assert.notNull(beanName, "\'beanName\' must not be null");
        Map var3 = this.singletonObjects;
		//線程安全
        synchronized(this.singletonObjects) {
            Object oldObject = this.singletonObjects.get(beanName);
            if(oldObject != null) {
                throw new IllegalStateException("Could not register object [" + singletonObject + "] under bean name \'" + beanName + "\': there is already object [" + oldObject + "] bound");
            } else {
                this.addSingleton(beanName, singletonObject);
            }
        }
    }
	//添加一個單例bean
    protected void addSingleton(String beanName, Object singletonObject) {
        Map var3 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            this.singletonObjects.put(beanName, singletonObject != null?singletonObject:NULL_OBJECT);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.add(beanName);
        }
    }
	//添加一個單例singletonFactory
    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(singletonFactory, "Singleton factory must not be null");
        Map var3 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            if(!this.singletonObjects.containsKey(beanName)) {
                this.singletonFactories.put(beanName, singletonFactory);
                this.earlySingletonObjects.remove(beanName);
                this.registeredSingletons.add(beanName);
            }

        }
    }
	//獲取一個單例bean根據beanName
    public Object getSingleton(String beanName) {
        return this.getSingleton(beanName, true);
    }
	//獲取一個單例bean根據beanName的具體實現
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//先從singletonObjects中獲取
        Object singletonObject = this.singletonObjects.get(beanName);
        if(singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
            Map var4 = this.singletonObjects;
            synchronized(this.singletonObjects) {
				//從緩存中獲取
                singletonObject = this.earlySingletonObjects.get(beanName);
                if(singletonObject == null && allowEarlyReference) {
                    ObjectFactory singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
                    if(singletonFactory != null) {
                        singletonObject = singletonFactory.getObject();
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }

        return singletonObject != NULL_OBJECT?singletonObject:null;
    }
	//根據beanName,singletonFactory獲取一個單例bean
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "\'beanName\' must not be null");
        Map var3 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            Object singletonObject = this.singletonObjects.get(beanName);
            if(singletonObject == null) {
                if(this.singletonsCurrentlyInDestruction) {
                    throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction (Do not request a bean from a BeanFactory in a destroy method implementation!)");
                }

                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Creating shared instance of singleton bean \'" + beanName + "\'");
                }

                this.beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = this.suppressedExceptions == null;
                if(recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet();
                }

                try {
                    singletonObject = singletonFactory.getObject();
                    newSingleton = true;
                } catch (IllegalStateException var16) {
                    singletonObject = this.singletonObjects.get(beanName);
                    if(singletonObject == null) {
                        throw var16;
                    }
                } catch (BeanCreationException var17) {
                    BeanCreationException ex = var17;
                    if(recordSuppressedExceptions) {
                        Iterator var8 = this.suppressedExceptions.iterator();

                        while(var8.hasNext()) {
                            Exception suppressedException = (Exception)var8.next();
                            ex.addRelatedCause(suppressedException);
                        }
                    }

                    throw ex;
                } finally {
                    if(recordSuppressedExceptions) {
                        this.suppressedExceptions = null;
                    }

                    this.afterSingletonCreation(beanName);
                }

                if(newSingleton) {
                    this.addSingleton(beanName, singletonObject);
                }
            }

            return singletonObject != NULL_OBJECT?singletonObject:null;
        }
    }

    protected void onSuppressedException(Exception ex) {
        Map var2 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            if(this.suppressedExceptions != null) {
                this.suppressedExceptions.add(ex);
            }

        }
    }

    protected void removeSingleton(String beanName) {
        Map var2 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            this.singletonObjects.remove(beanName);
            this.singletonFactories.remove(beanName);
            this.earlySingletonObjects.remove(beanName);
            this.registeredSingletons.remove(beanName);
        }
    }

    public boolean containsSingleton(String beanName) {
        return this.singletonObjects.containsKey(beanName);
    }

    public String[] getSingletonNames() {
        Map var1 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            return StringUtils.toStringArray(this.registeredSingletons);
        }
    }

    public int getSingletonCount() {
        Map var1 = this.singletonObjects;
        synchronized(this.singletonObjects) {
            return this.registeredSingletons.size();
        }
    }

    public void setCurrentlyInCreation(String beanName, boolean inCreation) {
        Assert.notNull(beanName, "Bean name must not be null");
        if(!inCreation) {
            this.inCreationCheckExclusions.add(beanName);
        } else {
            this.inCreationCheckExclusions.remove(beanName);
        }

    }

    public boolean isCurrentlyInCreation(String beanName) {
        Assert.notNull(beanName, "Bean name must not be null");
        return !this.inCreationCheckExclusions.contains(beanName) && this.isActuallyInCreation(beanName);
    }

    protected boolean isActuallyInCreation(String beanName) {
        return this.isSingletonCurrentlyInCreation(beanName);
    }

    public boolean isSingletonCurrentlyInCreation(String beanName) {
        return this.singletonsCurrentlyInCreation.contains(beanName);
    }

    protected void beforeSingletonCreation(String beanName) {
        if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }

    protected void afterSingletonCreation(String beanName) {
        if(!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
            throw new IllegalStateException("Singleton \'" + beanName + "\' isn\'t currently in creation");
        }
    }

    public void registerDisposableBean(String beanName, DisposableBean bean) {
        Map var3 = this.disposableBeans;
        synchronized(this.disposableBeans) {
            this.disposableBeans.put(beanName, bean);
        }
    }

    public void registerContainedBean(String containedBeanName, String containingBeanName) {
        Set containedBeans = (Set)this.containedBeanMap.get(containingBeanName);
        if(containedBeans == null || !containedBeans.contains(containedBeanName)) {
            Map var4 = this.containedBeanMap;
            synchronized(this.containedBeanMap) {
                Object containedBeans1 = (Set)this.containedBeanMap.get(containingBeanName);
                if(containedBeans1 == null) {
                    containedBeans1 = new LinkedHashSet(8);
                    this.containedBeanMap.put(containingBeanName, containedBeans1);
                }

                ((Set)containedBeans1).add(containedBeanName);
            }

            this.registerDependentBean(containedBeanName, containingBeanName);
        }
    }

    public void registerDependentBean(String beanName, String dependentBeanName) {
        String canonicalName = this.canonicalName(beanName);
        Set dependentBeans = (Set)this.dependentBeanMap.get(canonicalName);
        if(dependentBeans == null || !dependentBeans.contains(dependentBeanName)) {
            Map var5 = this.dependentBeanMap;
            synchronized(this.dependentBeanMap) {
                Object dependentBeans1 = (Set)this.dependentBeanMap.get(canonicalName);
                if(dependentBeans1 == null) {
                    dependentBeans1 = new LinkedHashSet(8);
                    this.dependentBeanMap.put(canonicalName, dependentBeans1);
                }

                ((Set)dependentBeans1).add(dependentBeanName);
            }

            var5 = this.dependenciesForBeanMap;
            synchronized(this.dependenciesForBeanMap) {
                Object dependenciesForBean = (Set)this.dependenciesForBeanMap.get(dependentBeanName);
                if(dependenciesForBean == null) {
                    dependenciesForBean = new LinkedHashSet(8);
                    this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
                }

                ((Set)dependenciesForBean).add(canonicalName);
            }
        }
    }

    protected boolean isDependent(String beanName, String dependentBeanName) {
        return this.isDependent(beanName, dependentBeanName, (Set)null);
    }

    private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
        if(alreadySeen != null && ((Set)alreadySeen).contains(beanName)) {
            return false;
        } else {
            String canonicalName = this.canonicalName(beanName);
            Set dependentBeans = (Set)this.dependentBeanMap.get(canonicalName);
            if(dependentBeans == null) {
                return false;
            } else if(dependentBeans.contains(dependentBeanName)) {
                return true;
            } else {
                Iterator var6 = dependentBeans.iterator();

                String transitiveDependency;
                do {
                    if(!var6.hasNext()) {
                        return false;
                    }

                    transitiveDependency = (String)var6.next();
                    if(alreadySeen == null) {
                        alreadySeen = new HashSet();
                    }

                    ((Set)alreadySeen).add(beanName);
                } while(!this.isDependent(transitiveDependency, dependentBeanName, (Set)alreadySeen));

                return true;
            }
        }
    }

    protected boolean hasDependentBean(String beanName) {
        return this.dependentBeanMap.containsKey(beanName);
    }

    public String[] getDependentBeans(String beanName) {
        Set dependentBeans = (Set)this.dependentBeanMap.get(beanName);
        return dependentBeans == null?new String[0]:StringUtils.toStringArray(dependentBeans);
    }

    public String[] getDependenciesForBean(String beanName) {
        Set dependenciesForBean = (Set)this.dependenciesForBeanMap.get(beanName);
        return dependenciesForBean == null?new String[0]:(String[])dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
    }

    public void destroySingletons() {
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Destroying singletons in " + this);
        }

        Map disposableBeanNames = this.singletonObjects;
        synchronized(this.singletonObjects) {
            this.singletonsCurrentlyInDestruction = true;
        }

        Map i = this.disposableBeans;
        String[] var8;
        synchronized(this.disposableBeans) {
            var8 = StringUtils.toStringArray(this.disposableBeans.keySet());
        }

        for(int var9 = var8.length - 1; var9 >= 0; --var9) {
            this.destroySingleton(var8[var9]);
        }

        this.containedBeanMap.clear();
        this.dependentBeanMap.clear();
        this.dependenciesForBeanMap.clear();
        i = this.singletonObjects;
        synchronized(this.singletonObjects) {
            this.singletonObjects.clear();
            this.singletonFactories.clear();
            this.earlySingletonObjects.clear();
            this.registeredSingletons.clear();
            this.singletonsCurrentlyInDestruction = false;
        }
    }

    public void destroySingleton(String beanName) {
        this.removeSingleton(beanName);
        Map var3 = this.disposableBeans;
        DisposableBean disposableBean;
        synchronized(this.disposableBeans) {
            disposableBean = (DisposableBean)this.disposableBeans.remove(beanName);
        }

        this.destroyBean(beanName, disposableBean);
    }

    protected void destroyBean(String beanName, DisposableBean bean) {
        Set dependencies = (Set)this.dependentBeanMap.remove(beanName);
        if(dependencies != null) {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Retrieved dependent beans for bean \'" + beanName + "\': " + dependencies);
            }

            Iterator containedBeans = dependencies.iterator();

            while(containedBeans.hasNext()) {
                String dependentBeanName = (String)containedBeans.next();
                this.destroySingleton(dependentBeanName);
            }
        }

        if(bean != null) {
            try {
                bean.destroy();
            } catch (Throwable var10) {
                this.logger.error("Destroy method on bean with name \'" + beanName + "\' threw an exception", var10);
            }
        }

        Set containedBeans1 = (Set)this.containedBeanMap.remove(beanName);
        if(containedBeans1 != null) {
            Iterator dependentBeanName1 = containedBeans1.iterator();

            while(dependentBeanName1.hasNext()) {
                String it = (String)dependentBeanName1.next();
                this.destroySingleton(it);
            }
        }

        Map dependentBeanName2 = this.dependentBeanMap;
        synchronized(this.dependentBeanMap) {
            Iterator it1 = this.dependentBeanMap.entrySet().iterator();

            while(true) {
                if(!it1.hasNext()) {
                    break;
                }

                Entry entry = (Entry)it1.next();
                Set dependenciesToClean = (Set)entry.getValue();
                dependenciesToClean.remove(beanName);
                if(dependenciesToClean.isEmpty()) {
                    it1.remove();
                }
            }
        }

        this.dependenciesForBeanMap.remove(beanName);
    }

    public final Object getSingletonMutex() {
        return this.singletonObjects;
    }
}

六、FactoryBeanRegistrySupport(extends DefaultSingletonBeanRegistry)

在默認單例bean註冊的基礎之上增長了對

private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap(16);

的緩存

public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
    //緩存factoryBean
    private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap(16);

    public FactoryBeanRegistrySupport() {
    }

    protected Class<?> getTypeForFactoryBean(final FactoryBean<?> factoryBean) {
        try {
            return System.getSecurityManager() != null?(Class)AccessController.doPrivileged(new PrivilegedAction() {
                public Class<?> run() {
                    return factoryBean.getObjectType();
                }
            }, this.getAccessControlContext()):factoryBean.getObjectType();
        } catch (Throwable var3) {
            this.logger.warn("FactoryBean threw exception from getObjectType, despite the contract saying that it should return null if the type of its object cannot be determined yet", var3);
            return null;
        }
    }

    protected Object getCachedObjectForFactoryBean(String beanName) {
        Object object = this.factoryBeanObjectCache.get(beanName);
        return object != NULL_OBJECT?object:null;
    }

    protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        if(factory.isSingleton() && this.containsSingleton(beanName)) {
            synchronized(this.getSingletonMutex()) {
                Object ex = this.factoryBeanObjectCache.get(beanName);
                if(ex == null) {
                    ex = this.doGetObjectFromFactoryBean(factory, beanName);
                    Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
                    if(alreadyThere != null) {
                        ex = alreadyThere;
                    } else {
                        if(ex != null && shouldPostProcess) {
                            try {
                                ex = this.postProcessObjectFromFactoryBean(ex, beanName);
                            } catch (Throwable var9) {
                                throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s singleton object failed", var9);
                            }
                        }

                        this.factoryBeanObjectCache.put(beanName, ex != null?ex:NULL_OBJECT);
                    }
                }

                return ex != NULL_OBJECT?ex:null;
            }
        } else {
            Object object = this.doGetObjectFromFactoryBean(factory, beanName);
            if(object != null && shouldPostProcess) {
                try {
                    object = this.postProcessObjectFromFactoryBean(object, beanName);
                } catch (Throwable var11) {
                    throw new BeanCreationException(beanName, "Post-processing of FactoryBean\'s object failed", var11);
                }
            }

            return object;
        }
    }

    private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, String beanName) throws BeanCreationException {
        Object object;
        try {
            if(System.getSecurityManager() != null) {
                AccessControlContext ex = this.getAccessControlContext();

                try {
                    object = AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            return factory.getObject();
                        }
                    }, ex);
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {
                object = factory.getObject();
            }
        } catch (FactoryBeanNotInitializedException var7) {
            throw new BeanCurrentlyInCreationException(beanName, var7.toString());
        } catch (Throwable var8) {
            throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var8);
        }

        if(object == null && this.isSingletonCurrentlyInCreation(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
        } else {
            return object;
        }
    }

    protected Object postProcessObjectFromFactoryBean(Object object, String beanName) throws BeansException {
        return object;
    }

    protected FactoryBean<?> getFactoryBean(String beanName, Object beanInstance) throws BeansException {
        if(!(beanInstance instanceof FactoryBean)) {
            throw new BeanCreationException(beanName, "Bean instance of type [" + beanInstance.getClass() + "] is not a FactoryBean");
        } else {
            return (FactoryBean)beanInstance;
        }
    }

    protected void removeSingleton(String beanName) {
        super.removeSingleton(beanName);
        this.factoryBeanObjectCache.remove(beanName);
    }

    protected AccessControlContext getAccessControlContext() {
        return AccessController.getContext();
    }
}

七、BeanFactory bean工廠接口(信息查詢類)

public interface BeanFactory {
	//這裏是一個常理:工廠bean前綴
    String FACTORY_BEAN_PREFIX = "&";
	//獲取一個bean(return:object)
    Object getBean(String var1) throws BeansException;
	//獲取一個bean,指定class返回也是這個類型
    <T> T getBean(String var1, Class<T> var2) throws BeansException;
	//根據class獲取一個bean
    <T> T getBean(Class<T> var1) throws BeansException;
	//獲取一個bean
    Object getBean(String var1, Object... var2) throws BeansException;

    <T> T getBean(Class<T> var1, Object... var2) throws BeansException;
	//判斷一個bean是否存在
    boolean containsBean(String var1);
	//判斷一個bean是不是單例
    boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
	
    boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;

    boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;

    Class<?> getType(String var1) throws NoSuchBeanDefinitionException;

    String[] getAliases(String var1);
}

八、ListableBeanFactory 接口(信息查詢類)

public interface ListableBeanFactory extends BeanFactory {
	//判斷註冊表中是否包含BeanDefinition
    boolean containsBeanDefinition(String var1);
	//獲取註冊表中BeanDefinition的數量
    int getBeanDefinitionCount();
	//獲取註冊表中BeanDefinition的name(arrays)
    String[] getBeanDefinitionNames();
	//根據bean類型獲取beanNames(arrays) 參數ResolvableType
    String[] getBeanNamesForType(ResolvableType var1);
	//根據bean類型獲取beanNames(arrays) 參數Class
    String[] getBeanNamesForType(Class<?> var1);

    String[] getBeanNamesForType(Class<?> var1, boolean var2, boolean var3);

    <T> Map<String, T> getBeansOfType(Class<T> var1) throws BeansException;

    <T> Map<String, T> getBeansOfType(Class<T> var1, boolean var2, boolean var3) throws BeansException;
	//根據註冊獲取beanNames
    String[] getBeanNamesForAnnotation(Class<? extends Annotation> var1);

    Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> var1) throws BeansException;
    //查找全部具備提供註解類型(Annotation)的bean,返回bean名稱的映射,並使用相應的bean實例。 
    <A extends Annotation> A findAnnotationOnBean(String var1, Class<A> var2) throws NoSuchBeanDefinitionException;
}
//本接口主要提供了以下幾個功能
//一、判斷註冊表中是否存在BeanDefinition
//二、根據各類參數獲取beanNames信息(主要分了按ResolvableType類型,Class,Annotation)

九、HierarchicalBeanFactory 接口

//這個接口比較有意思。從接口中咱們看見提供了獲取父類接口的一個實現
public interface HierarchicalBeanFactory extends BeanFactory {
	//返回父bean工廠,或null,若是沒有。  
    BeanFactory getParentBeanFactory();
    //返回本地bean工廠是否包含給定名稱的bean,忽略在祖先上下文中定義的bean。
    boolean containsLocalBean(String var1);
}

十、ConfigurableBeanFactory 配置bean工廠接口

注:這個類的接口比較多,也很複雜

public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
    String SCOPE_SINGLETON = "singleton";
    String SCOPE_PROTOTYPE = "prototype";

    void setParentBeanFactory(BeanFactory var1) throws IllegalStateException;

    void setBeanClassLoader(ClassLoader var1);

    ClassLoader getBeanClassLoader();

    void setTempClassLoader(ClassLoader var1);

    ClassLoader getTempClassLoader();

    void setCacheBeanMetadata(boolean var1);

    boolean isCacheBeanMetadata();

    void setBeanExpressionResolver(BeanExpressionResolver var1);

    BeanExpressionResolver getBeanExpressionResolver();

    void setConversionService(ConversionService var1);

    ConversionService getConversionService();

    void addPropertyEditorRegistrar(PropertyEditorRegistrar var1);

    void registerCustomEditor(Class<?> var1, Class<? extends PropertyEditor> var2);

    void copyRegisteredEditorsTo(PropertyEditorRegistry var1);

    void setTypeConverter(TypeConverter var1);

    TypeConverter getTypeConverter();

    void addEmbeddedValueResolver(StringValueResolver var1);

    boolean hasEmbeddedValueResolver();

    String resolveEmbeddedValue(String var1);

    void addBeanPostProcessor(BeanPostProcessor var1);

    int getBeanPostProcessorCount();

    void registerScope(String var1, Scope var2);

    String[] getRegisteredScopeNames();

    Scope getRegisteredScope(String var1);

    AccessControlContext getAccessControlContext();

    void copyConfigurationFrom(ConfigurableBeanFactory var1);

    void registerAlias(String var1, String var2) throws BeanDefinitionStoreException;

    void resolveAliases(StringValueResolver var1);

    BeanDefinition getMergedBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    boolean isFactoryBean(String var1) throws NoSuchBeanDefinitionException;

    void setCurrentlyInCreation(String var1, boolean var2);

    boolean isCurrentlyInCreation(String var1);

    void registerDependentBean(String var1, String var2);

    String[] getDependentBeans(String var1);

    String[] getDependenciesForBean(String var1);

    void destroyBean(String var1, Object var2);

    void destroyScopedBean(String var1);

    void destroySingletons();
}

十一、AbstractBeanFactory 抽象bean工廠實現

(extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory)

繼承了FactoryBeanRegistrySupport實現了ConfigurableBeanFactory接口

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    private BeanFactory parentBeanFactory;
    private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
    private ClassLoader tempClassLoader;
    private boolean cacheBeanMetadata = true;
    private BeanExpressionResolver beanExpressionResolver;
    private ConversionService conversionService;
    private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet(4);
    private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap(4);
    private TypeConverter typeConverter;
    private final List<StringValueResolver> embeddedValueResolvers = new LinkedList();
    private final List<BeanPostProcessor> beanPostProcessors = new ArrayList();
    private boolean hasInstantiationAwareBeanPostProcessors;
    private boolean hasDestructionAwareBeanPostProcessors;
    private final Map<String, Scope> scopes = new LinkedHashMap(8);
    private SecurityContextProvider securityContextProvider;
    private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap(256);
    private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap(256));
    private final ThreadLocal<Object> prototypesCurrentlyInCreation = new NamedThreadLocal("Prototype beans currently in creation");

    public AbstractBeanFactory() {
    }

    public AbstractBeanFactory(BeanFactory parentBeanFactory) {
        this.parentBeanFactory = parentBeanFactory;
    }

    public Object getBean(String name) throws BeansException {
        return this.doGetBean(name, (Class)null, (Object[])null, false);
    }

    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return this.doGetBean(name, requiredType, (Object[])null, false);
    }

    public Object getBean(String name, Object... args) throws BeansException {
        return this.doGetBean(name, (Class)null, args, false);
    }

    public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
        return this.doGetBean(name, requiredType, args, false);
    }

    protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
        final String beanName = this.transformedBeanName(name);
        Object sharedInstance = this.getSingleton(beanName);
        Object bean;
        if(sharedInstance != null && args == null) {
            if(this.logger.isDebugEnabled()) {
                if(this.isSingletonCurrentlyInCreation(beanName)) {
                    this.logger.debug("Returning eagerly cached instance of singleton bean \'" + beanName + "\' that is not fully initialized yet - a consequence of a circular reference");
                } else {
                    this.logger.debug("Returning cached instance of singleton bean \'" + beanName + "\'");
                }
            }

            bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
        } else {
            if(this.isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            BeanFactory ex = this.getParentBeanFactory();
            if(ex != null && !this.containsBeanDefinition(beanName)) {
                String var24 = this.originalBeanName(name);
                if(args != null) {
                    return ex.getBean(var24, args);
                }

                return ex.getBean(var24, requiredType);
            }

            if(!typeCheckOnly) {
                this.markBeanAsCreated(beanName);
            }

            try {
                final RootBeanDefinition ex1 = this.getMergedLocalBeanDefinition(beanName);
                this.checkMergedBeanDefinition(ex1, beanName, args);
                String[] dependsOn = ex1.getDependsOn();
                String[] scopeName;
                if(dependsOn != null) {
                    scopeName = dependsOn;
                    int scope = dependsOn.length;

                    for(int ex2 = 0; ex2 < scope; ++ex2) {
                        String dep = scopeName[ex2];
                        if(this.isDependent(beanName, dep)) {
                            throw new BeanCreationException(ex1.getResourceDescription(), beanName, "Circular depends-on relationship between \'" + beanName + "\' and \'" + dep + "\'");
                        }

                        this.registerDependentBean(dep, beanName);
                        this.getBean(dep);
                    }
                }

                if(ex1.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, new ObjectFactory() {
                        public Object getObject() throws BeansException {
                            try {
                                return AbstractBeanFactory.this.createBean(beanName, ex1, args);
                            } catch (BeansException var2) {
                                AbstractBeanFactory.this.destroySingleton(beanName);
                                throw var2;
                            }
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, ex1);
                } else if(ex1.isPrototype()) {
                    scopeName = null;

                    Object var25;
                    try {
                        this.beforePrototypeCreation(beanName);
                        var25 = this.createBean(beanName, ex1, args);
                    } finally {
                        this.afterPrototypeCreation(beanName);
                    }

                    bean = this.getObjectForBeanInstance(var25, name, beanName, ex1);
                } else {
                    String var26 = ex1.getScope();
                    Scope var27 = (Scope)this.scopes.get(var26);
                    if(var27 == null) {
                        throw new IllegalStateException("No Scope registered for scope name \'" + var26 + "\'");
                    }

                    try {
                        Object var28 = var27.get(beanName, new ObjectFactory() {
                            public Object getObject() throws BeansException {
                                AbstractBeanFactory.this.beforePrototypeCreation(beanName);

                                Object var1;
                                try {
                                    var1 = AbstractBeanFactory.this.createBean(beanName, ex1, args);
                                } finally {
                                    AbstractBeanFactory.this.afterPrototypeCreation(beanName);
                                }

                                return var1;
                            }
                        });
                        bean = this.getObjectForBeanInstance(var28, name, beanName, ex1);
                    } catch (IllegalStateException var21) {
                        throw new BeanCreationException(beanName, "Scope \'" + var26 + "\' 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", var21);
                    }
                }
            } catch (BeansException var23) {
                this.cleanupAfterBeanCreationFailure(beanName);
                throw var23;
            }
        }

        if(requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
            try {
                return this.getTypeConverter().convertIfNecessary(bean, requiredType);
            } catch (TypeMismatchException var22) {
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Failed to convert bean \'" + name + "\' to required type \'" + ClassUtils.getQualifiedName(requiredType) + "\'", var22);
                }

                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        } else {
            return bean;
        }
    }

    public boolean containsBean(String name) {
        String beanName = this.transformedBeanName(name);
        if(!this.containsSingleton(beanName) && !this.containsBeanDefinition(beanName)) {
            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            return parentBeanFactory != null && parentBeanFactory.containsBean(this.originalBeanName(name));
        } else {
            return !BeanFactoryUtils.isFactoryDereference(name) || this.isFactoryBean(name);
        }
    }

    public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        String beanName = this.transformedBeanName(name);
        Object beanInstance = this.getSingleton(beanName, false);
        if(beanInstance != null) {
            return !(beanInstance instanceof FactoryBean)?!BeanFactoryUtils.isFactoryDereference(name):BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean)beanInstance).isSingleton();
        } else if(this.containsSingleton(beanName)) {
            return true;
        } else {
            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                return parentBeanFactory.isSingleton(this.originalBeanName(name));
            } else {
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                if(mbd.isSingleton()) {
                    if(this.isFactoryBean(beanName, mbd)) {
                        if(BeanFactoryUtils.isFactoryDereference(name)) {
                            return true;
                        } else {
                            FactoryBean factoryBean = (FactoryBean)this.getBean("&" + beanName);
                            return factoryBean.isSingleton();
                        }
                    } else {
                        return !BeanFactoryUtils.isFactoryDereference(name);
                    }
                } else {
                    return false;
                }
            }
        }
    }

    public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
        String beanName = this.transformedBeanName(name);
        BeanFactory parentBeanFactory = this.getParentBeanFactory();
        if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
            return parentBeanFactory.isPrototype(this.originalBeanName(name));
        } else {
            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            if(mbd.isPrototype()) {
                return !BeanFactoryUtils.isFactoryDereference(name) || this.isFactoryBean(beanName, mbd);
            } else if(BeanFactoryUtils.isFactoryDereference(name)) {
                return false;
            } else if(this.isFactoryBean(beanName, mbd)) {
                final FactoryBean fb = (FactoryBean)this.getBean("&" + beanName);
                return System.getSecurityManager() != null?((Boolean)AccessController.doPrivileged(new PrivilegedAction() {
                    public Boolean run() {
                        return Boolean.valueOf(fb instanceof SmartFactoryBean && ((SmartFactoryBean)fb).isPrototype() || !fb.isSingleton());
                    }
                }, this.getAccessControlContext())).booleanValue():fb instanceof SmartFactoryBean && ((SmartFactoryBean)fb).isPrototype() || !fb.isSingleton();
            } else {
                return false;
            }
        }
    }

    public boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException {
        String beanName = this.transformedBeanName(name);
        Object beanInstance = this.getSingleton(beanName, false);
        Class classToMatch;
        if(beanInstance != null) {
            if(beanInstance instanceof FactoryBean) {
                if(BeanFactoryUtils.isFactoryDereference(name)) {
                    return typeToMatch.isInstance(beanInstance);
                } else {
                    Class parentBeanFactory2 = this.getTypeForFactoryBean((FactoryBean)beanInstance);
                    return parentBeanFactory2 != null && typeToMatch.isAssignableFrom(parentBeanFactory2);
                }
            } else {
                if(!BeanFactoryUtils.isFactoryDereference(name)) {
                    if(typeToMatch.isInstance(beanInstance)) {
                        return true;
                    }

                    if(typeToMatch.hasGenerics() && this.containsBeanDefinition(beanName)) {
                        RootBeanDefinition parentBeanFactory1 = this.getMergedLocalBeanDefinition(beanName);
                        Class mbd1 = parentBeanFactory1.getTargetType();
                        if(mbd1 != null && mbd1 != ClassUtils.getUserClass(beanInstance) && typeToMatch.isAssignableFrom(mbd1)) {
                            classToMatch = typeToMatch.resolve();
                            return classToMatch == null || classToMatch.isInstance(beanInstance);
                        }
                    }
                }

                return false;
            }
        } else if(this.containsSingleton(beanName) && !this.containsBeanDefinition(beanName)) {
            return false;
        } else {
            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                return parentBeanFactory.isTypeMatch(this.originalBeanName(name), typeToMatch);
            } else {
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                classToMatch = typeToMatch.resolve();
                if(classToMatch == null) {
                    classToMatch = FactoryBean.class;
                }

                Class[] typesToMatch = FactoryBean.class == classToMatch?new Class[]{classToMatch}:new Class[]{FactoryBean.class, classToMatch};
                BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                if(dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
                    RootBeanDefinition beanType = this.getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
                    Class resolvableType = this.predictBeanType(dbd.getBeanName(), beanType, typesToMatch);
                    if(resolvableType != null && !FactoryBean.class.isAssignableFrom(resolvableType)) {
                        return typeToMatch.isAssignableFrom(resolvableType);
                    }
                }

                Class beanType1 = this.predictBeanType(beanName, mbd, typesToMatch);
                if(beanType1 == null) {
                    return false;
                } else {
                    if(FactoryBean.class.isAssignableFrom(beanType1)) {
                        if(!BeanFactoryUtils.isFactoryDereference(name)) {
                            beanType1 = this.getTypeForFactoryBean(beanName, mbd);
                            if(beanType1 == null) {
                                return false;
                            }
                        }
                    } else if(BeanFactoryUtils.isFactoryDereference(name)) {
                        beanType1 = this.predictBeanType(beanName, mbd, new Class[]{FactoryBean.class});
                        if(beanType1 == null || !FactoryBean.class.isAssignableFrom(beanType1)) {
                            return false;
                        }
                    }

                    ResolvableType resolvableType1 = mbd.targetType;
                    if(resolvableType1 == null) {
                        resolvableType1 = mbd.factoryMethodReturnType;
                    }

                    return resolvableType1 != null && resolvableType1.resolve() == beanType1?typeToMatch.isAssignableFrom(resolvableType1):typeToMatch.isAssignableFrom(beanType1);
                }
            }
        }
    }

    public boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException {
        return this.isTypeMatch(name, ResolvableType.forRawClass(typeToMatch));
    }

    public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
        String beanName = this.transformedBeanName(name);
        Object beanInstance = this.getSingleton(beanName, false);
        if(beanInstance != null) {
            return beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)?this.getTypeForFactoryBean((FactoryBean)beanInstance):beanInstance.getClass();
        } else if(this.containsSingleton(beanName) && !this.containsBeanDefinition(beanName)) {
            return null;
        } else {
            BeanFactory parentBeanFactory = this.getParentBeanFactory();
            if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
                return parentBeanFactory.getType(this.originalBeanName(name));
            } else {
                RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
                BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                if(dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
                    RootBeanDefinition beanClass = this.getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
                    Class targetClass = this.predictBeanType(dbd.getBeanName(), beanClass, new Class[0]);
                    if(targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
                        return targetClass;
                    }
                }

                Class beanClass1 = this.predictBeanType(beanName, mbd, new Class[0]);
                return beanClass1 != null && FactoryBean.class.isAssignableFrom(beanClass1)?(!BeanFactoryUtils.isFactoryDereference(name)?this.getTypeForFactoryBean(beanName, mbd):beanClass1):(!BeanFactoryUtils.isFactoryDereference(name)?beanClass1:null);
            }
        }
    }

    public String[] getAliases(String name) {
        String beanName = this.transformedBeanName(name);
        ArrayList aliases = new ArrayList();
        boolean factoryPrefix = name.startsWith("&");
        String fullBeanName = beanName;
        if(factoryPrefix) {
            fullBeanName = "&" + beanName;
        }

        if(!fullBeanName.equals(name)) {
            aliases.add(fullBeanName);
        }

        String[] retrievedAliases = super.getAliases(beanName);
        String[] parentBeanFactory = retrievedAliases;
        int var8 = retrievedAliases.length;

        for(int var9 = 0; var9 < var8; ++var9) {
            String retrievedAlias = parentBeanFactory[var9];
            String alias = (factoryPrefix?"&":"") + retrievedAlias;
            if(!alias.equals(name)) {
                aliases.add(alias);
            }
        }

        if(!this.containsSingleton(beanName) && !this.containsBeanDefinition(beanName)) {
            BeanFactory var12 = this.getParentBeanFactory();
            if(var12 != null) {
                aliases.addAll(Arrays.asList(var12.getAliases(fullBeanName)));
            }
        }

        return StringUtils.toStringArray(aliases);
    }

    public BeanFactory getParentBeanFactory() {
        return this.parentBeanFactory;
    }

    public boolean containsLocalBean(String name) {
        String beanName = this.transformedBeanName(name);
        return (this.containsSingleton(beanName) || this.containsBeanDefinition(beanName)) && (!BeanFactoryUtils.isFactoryDereference(name) || this.isFactoryBean(beanName));
    }

    public void setParentBeanFactory(BeanFactory parentBeanFactory) {
        if(this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
            throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
        } else {
            this.parentBeanFactory = parentBeanFactory;
        }
    }

    public void setBeanClassLoader(ClassLoader beanClassLoader) {
        this.beanClassLoader = beanClassLoader != null?beanClassLoader:ClassUtils.getDefaultClassLoader();
    }

    public ClassLoader getBeanClassLoader() {
        return this.beanClassLoader;
    }

    public void setTempClassLoader(ClassLoader tempClassLoader) {
        this.tempClassLoader = tempClassLoader;
    }

    public ClassLoader getTempClassLoader() {
        return this.tempClassLoader;
    }

    public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
        this.cacheBeanMetadata = cacheBeanMetadata;
    }

    public boolean isCacheBeanMetadata() {
        return this.cacheBeanMetadata;
    }

    public void setBeanExpressionResolver(BeanExpressionResolver resolver) {
        this.beanExpressionResolver = resolver;
    }

    public BeanExpressionResolver getBeanExpressionResolver() {
        return this.beanExpressionResolver;
    }

    public void setConversionService(ConversionService conversionService) {
        this.conversionService = conversionService;
    }

    public ConversionService getConversionService() {
        return this.conversionService;
    }

    public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
        Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
        this.propertyEditorRegistrars.add(registrar);
    }

    public Set<PropertyEditorRegistrar> getPropertyEditorRegistrars() {
        return this.propertyEditorRegistrars;
    }

    public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
        Assert.notNull(requiredType, "Required type must not be null");
        Assert.notNull(propertyEditorClass, "PropertyEditor class must not be null");
        this.customEditors.put(requiredType, propertyEditorClass);
    }

    public void copyRegisteredEditorsTo(PropertyEditorRegistry registry) {
        this.registerCustomEditors(registry);
    }

    public Map<Class<?>, Class<? extends PropertyEditor>> getCustomEditors() {
        return this.customEditors;
    }

    public void setTypeConverter(TypeConverter typeConverter) {
        this.typeConverter = typeConverter;
    }

    protected TypeConverter getCustomTypeConverter() {
        return this.typeConverter;
    }

    public TypeConverter getTypeConverter() {
        TypeConverter customConverter = this.getCustomTypeConverter();
        if(customConverter != null) {
            return customConverter;
        } else {
            SimpleTypeConverter typeConverter = new SimpleTypeConverter();
            typeConverter.setConversionService(this.getConversionService());
            this.registerCustomEditors(typeConverter);
            return typeConverter;
        }
    }

    public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
        Assert.notNull(valueResolver, "StringValueResolver must not be null");
        this.embeddedValueResolvers.add(valueResolver);
    }

    public boolean hasEmbeddedValueResolver() {
        return !this.embeddedValueResolvers.isEmpty();
    }

    public String resolveEmbeddedValue(String value) {
        if(value == null) {
            return null;
        } else {
            String result = value;
            Iterator var3 = this.embeddedValueResolvers.iterator();

            do {
                if(!var3.hasNext()) {
                    return result;
                }

                StringValueResolver resolver = (StringValueResolver)var3.next();
                result = resolver.resolveStringValue(result);
            } while(result != null);

            return null;
        }
    }

    public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
        Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
        this.beanPostProcessors.remove(beanPostProcessor);
        this.beanPostProcessors.add(beanPostProcessor);
        if(beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
            this.hasInstantiationAwareBeanPostProcessors = true;
        }

        if(beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
            this.hasDestructionAwareBeanPostProcessors = true;
        }

    }

    public int getBeanPostProcessorCount() {
        return this.beanPostProcessors.size();
    }

    public List<BeanPostProcessor> getBeanPostProcessors() {
        return this.beanPostProcessors;
    }

    protected boolean hasInstantiationAwareBeanPostProcessors() {
        return this.hasInstantiationAwareBeanPostProcessors;
    }

    protected boolean hasDestructionAwareBeanPostProcessors() {
        return this.hasDestructionAwareBeanPostProcessors;
    }

    public void registerScope(String scopeName, Scope scope) {
        Assert.notNull(scopeName, "Scope identifier must not be null");
        Assert.notNull(scope, "Scope must not be null");
        if(!"singleton".equals(scopeName) && !"prototype".equals(scopeName)) {
            Scope previous = (Scope)this.scopes.put(scopeName, scope);
            if(previous != null && previous != scope) {
                if(this.logger.isInfoEnabled()) {
                    this.logger.info("Replacing scope \'" + scopeName + "\' from [" + previous + "] to [" + scope + "]");
                }
            } else if(this.logger.isDebugEnabled()) {
                this.logger.debug("Registering scope \'" + scopeName + "\' with implementation [" + scope + "]");
            }

        } else {
            throw new IllegalArgumentException("Cannot replace existing scopes \'singleton\' and \'prototype\'");
        }
    }

    public String[] getRegisteredScopeNames() {
        return StringUtils.toStringArray(this.scopes.keySet());
    }

    public Scope getRegisteredScope(String scopeName) {
        Assert.notNull(scopeName, "Scope identifier must not be null");
        return (Scope)this.scopes.get(scopeName);
    }

    public void setSecurityContextProvider(SecurityContextProvider securityProvider) {
        this.securityContextProvider = securityProvider;
    }

    public AccessControlContext getAccessControlContext() {
        return this.securityContextProvider != null?this.securityContextProvider.getAccessControlContext():AccessController.getContext();
    }

    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        Assert.notNull(otherFactory, "BeanFactory must not be null");
        this.setBeanClassLoader(otherFactory.getBeanClassLoader());
        this.setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
        this.setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
        this.setConversionService(otherFactory.getConversionService());
        if(otherFactory instanceof AbstractBeanFactory) {
            AbstractBeanFactory otherScopeNames = (AbstractBeanFactory)otherFactory;
            this.propertyEditorRegistrars.addAll(otherScopeNames.propertyEditorRegistrars);
            this.customEditors.putAll(otherScopeNames.customEditors);
            this.typeConverter = otherScopeNames.typeConverter;
            this.beanPostProcessors.addAll(otherScopeNames.beanPostProcessors);
            this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors || otherScopeNames.hasInstantiationAwareBeanPostProcessors;
            this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors || otherScopeNames.hasDestructionAwareBeanPostProcessors;
            this.scopes.putAll(otherScopeNames.scopes);
            this.securityContextProvider = otherScopeNames.securityContextProvider;
        } else {
            this.setTypeConverter(otherFactory.getTypeConverter());
            String[] var7 = otherFactory.getRegisteredScopeNames();
            String[] var3 = var7;
            int var4 = var7.length;

            for(int var5 = 0; var5 < var4; ++var5) {
                String scopeName = var3[var5];
                this.scopes.put(scopeName, otherFactory.getRegisteredScope(scopeName));
            }
        }

    }

    public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
        String beanName = this.transformedBeanName(name);
        return (BeanDefinition)(!this.containsBeanDefinition(beanName) && this.getParentBeanFactory() instanceof ConfigurableBeanFactory?((ConfigurableBeanFactory)this.getParentBeanFactory()).getMergedBeanDefinition(beanName):this.getMergedLocalBeanDefinition(beanName));
    }

    public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
        String beanName = this.transformedBeanName(name);
        Object beanInstance = this.getSingleton(beanName, false);
        return beanInstance != null?beanInstance instanceof FactoryBean:(this.containsSingleton(beanName)?false:(!this.containsBeanDefinition(beanName) && this.getParentBeanFactory() instanceof ConfigurableBeanFactory?((ConfigurableBeanFactory)this.getParentBeanFactory()).isFactoryBean(name):this.isFactoryBean(beanName, this.getMergedLocalBeanDefinition(beanName))));
    }

    public boolean isActuallyInCreation(String beanName) {
        return this.isSingletonCurrentlyInCreation(beanName) || this.isPrototypeCurrentlyInCreation(beanName);
    }

    protected boolean isPrototypeCurrentlyInCreation(String beanName) {
        Object curVal = this.prototypesCurrentlyInCreation.get();
        return curVal != null && (curVal.equals(beanName) || curVal instanceof Set && ((Set)curVal).contains(beanName));
    }

    protected void beforePrototypeCreation(String beanName) {
        Object curVal = this.prototypesCurrentlyInCreation.get();
        if(curVal == null) {
            this.prototypesCurrentlyInCreation.set(beanName);
        } else if(curVal instanceof String) {
            HashSet beanNameSet = new HashSet(2);
            beanNameSet.add((String)curVal);
            beanNameSet.add(beanName);
            this.prototypesCurrentlyInCreation.set(beanNameSet);
        } else {
            Set beanNameSet1 = (Set)curVal;
            beanNameSet1.add(beanName);
        }

    }

    protected void afterPrototypeCreation(String beanName) {
        Object curVal = this.prototypesCurrentlyInCreation.get();
        if(curVal instanceof String) {
            this.prototypesCurrentlyInCreation.remove();
        } else if(curVal instanceof Set) {
            Set beanNameSet = (Set)curVal;
            beanNameSet.remove(beanName);
            if(beanNameSet.isEmpty()) {
                this.prototypesCurrentlyInCreation.remove();
            }
        }

    }

    public void destroyBean(String beanName, Object beanInstance) {
        this.destroyBean(beanName, beanInstance, this.getMergedLocalBeanDefinition(beanName));
    }

    protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
        (new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), this.getAccessControlContext())).destroy();
    }

    public void destroyScopedBean(String beanName) {
        RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
        if(!mbd.isSingleton() && !mbd.isPrototype()) {
            String scopeName = mbd.getScope();
            Scope scope = (Scope)this.scopes.get(scopeName);
            if(scope == null) {
                throw new IllegalStateException("No Scope SPI registered for scope name \'" + scopeName + "\'");
            } else {
                Object bean = scope.remove(beanName);
                if(bean != null) {
                    this.destroyBean(beanName, bean, mbd);
                }

            }
        } else {
            throw new IllegalArgumentException("Bean name \'" + beanName + "\' does not correspond to an object in a mutable scope");
        }
    }

    protected String transformedBeanName(String name) {
        return this.canonicalName(BeanFactoryUtils.transformedBeanName(name));
    }

    protected String originalBeanName(String name) {
        String beanName = this.transformedBeanName(name);
        if(name.startsWith("&")) {
            beanName = "&" + beanName;
        }

        return beanName;
    }

    protected void initBeanWrapper(BeanWrapper bw) {
        bw.setConversionService(this.getConversionService());
        this.registerCustomEditors(bw);
    }

    protected void registerCustomEditors(PropertyEditorRegistry registry) {
        PropertyEditorRegistrySupport registrySupport = registry instanceof PropertyEditorRegistrySupport?(PropertyEditorRegistrySupport)registry:null;
        if(registrySupport != null) {
            registrySupport.useConfigValueEditors();
        }

        Iterator var3;
        if(!this.propertyEditorRegistrars.isEmpty()) {
            var3 = this.propertyEditorRegistrars.iterator();

            while(var3.hasNext()) {
                PropertyEditorRegistrar entry = (PropertyEditorRegistrar)var3.next();

                try {
                    entry.registerCustomEditors(registry);
                } catch (BeanCreationException var8) {
                    Throwable editorClass = var8.getMostSpecificCause();
                    if(editorClass instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException)editorClass;
                        if(this.isCurrentlyInCreation(bce.getBeanName())) {
                            if(this.logger.isDebugEnabled()) {
                                this.logger.debug("PropertyEditorRegistrar [" + entry.getClass().getName() + "] failed because it tried to obtain currently created bean \'" + var8.getBeanName() + "\': " + var8.getMessage());
                            }

                            this.onSuppressedException(var8);
                            continue;
                        }
                    }

                    throw var8;
                }
            }
        }

        if(!this.customEditors.isEmpty()) {
            var3 = this.customEditors.entrySet().iterator();

            while(var3.hasNext()) {
                Entry entry1 = (Entry)var3.next();
                Class requiredType = (Class)entry1.getKey();
                Class editorClass1 = (Class)entry1.getValue();
                registry.registerCustomEditor(requiredType, (PropertyEditor)BeanUtils.instantiateClass(editorClass1));
            }
        }

    }

    protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
        RootBeanDefinition mbd = (RootBeanDefinition)this.mergedBeanDefinitions.get(beanName);
        return mbd != null?mbd:this.getMergedBeanDefinition(beanName, this.getBeanDefinition(beanName));
    }

    protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) throws BeanDefinitionStoreException {
        return this.getMergedBeanDefinition(beanName, bd, (BeanDefinition)null);
    }

    protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException {
        Map var4 = this.mergedBeanDefinitions;
        synchronized(this.mergedBeanDefinitions) {
            RootBeanDefinition mbd = null;
            if(containingBd == null) {
                mbd = (RootBeanDefinition)this.mergedBeanDefinitions.get(beanName);
            }

            if(mbd == null) {
                if(bd.getParentName() == null) {
                    if(bd instanceof RootBeanDefinition) {
                        mbd = ((RootBeanDefinition)bd).cloneBeanDefinition();
                    } else {
                        mbd = new RootBeanDefinition(bd);
                    }
                } else {
                    BeanDefinition pbd;
                    try {
                        String ex = this.transformedBeanName(bd.getParentName());
                        if(!beanName.equals(ex)) {
                            pbd = this.getMergedBeanDefinition(ex);
                        } else {
                            BeanFactory parent = this.getParentBeanFactory();
                            if(!(parent instanceof ConfigurableBeanFactory)) {
                                throw new NoSuchBeanDefinitionException(ex, "Parent name \'" + ex + "\' is equal to bean name \'" + beanName + "\': cannot be resolved without an AbstractBeanFactory parent");
                            }

                            pbd = ((ConfigurableBeanFactory)parent).getMergedBeanDefinition(ex);
                        }
                    } catch (NoSuchBeanDefinitionException var10) {
                        throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition \'" + bd.getParentName() + "\'", var10);
                    }

                    mbd = new RootBeanDefinition(pbd);
                    mbd.overrideFrom(bd);
                }

                if(!StringUtils.hasLength(mbd.getScope())) {
                    mbd.setScope("singleton");
                }

                if(containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                    mbd.setScope(containingBd.getScope());
                }

                if(containingBd == null && this.isCacheBeanMetadata()) {
                    this.mergedBeanDefinitions.put(beanName, mbd);
                }
            }

            return mbd;
        }
    }

    protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args) throws BeanDefinitionStoreException {
        if(mbd.isAbstract()) {
            throw new BeanIsAbstractException(beanName);
        }
    }

    protected void clearMergedBeanDefinition(String beanName) {
        this.mergedBeanDefinitions.remove(beanName);
    }

    public void clearMetadataCache() {
        Iterator mergedBeans = this.mergedBeanDefinitions.keySet().iterator();

        while(mergedBeans.hasNext()) {
            if(!this.isBeanEligibleForMetadataCaching((String)mergedBeans.next())) {
                mergedBeans.remove();
            }
        }

    }

    protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class... typesToMatch) throws CannotLoadBeanClassException {
        try {
            return mbd.hasBeanClass()?mbd.getBeanClass():(System.getSecurityManager() != null?(Class)AccessController.doPrivileged(new PrivilegedExceptionAction() {
                public Class<?> run() throws Exception {
                    return AbstractBeanFactory.this.doResolveBeanClass(mbd, typesToMatch);
                }
            }, this.getAccessControlContext()):this.doResolveBeanClass(mbd, typesToMatch));
        } catch (PrivilegedActionException var6) {
            ClassNotFoundException ex = (ClassNotFoundException)var6.getException();
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
        } catch (ClassNotFoundException var7) {
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), var7);
        } catch (LinkageError var8) {
            throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), var8);
        }
    }

    private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException {
        ClassLoader beanClassLoader = this.getBeanClassLoader();
        ClassLoader classLoaderToUse = beanClassLoader;
        if(!ObjectUtils.isEmpty(typesToMatch)) {
            ClassLoader className = this.getTempClassLoader();
            if(className != null) {
                classLoaderToUse = className;
                if(className instanceof DecoratingClassLoader) {
                    DecoratingClassLoader evaluated = (DecoratingClassLoader)className;
                    Class[] var7 = typesToMatch;
                    int var8 = typesToMatch.length;

                    for(int var9 = 0; var9 < var8; ++var9) {
                        Class typeToMatch = var7[var9];
                        evaluated.excludeClass(typeToMatch.getName());
                    }
                }
            }
        }

        String var11 = mbd.getBeanClassName();
        if(var11 != null) {
            Object var12 = this.evaluateBeanDefinitionString(var11, mbd);
            if(!var11.equals(var12)) {
                if(var12 instanceof Class) {
                    return (Class)var12;
                }

                if(var12 instanceof String) {
                    return ClassUtils.forName((String)var12, classLoaderToUse);
                }

                throw new IllegalStateException("Invalid class name expression result: " + var12);
            }

            if(classLoaderToUse != beanClassLoader) {
                return ClassUtils.forName(var11, classLoaderToUse);
            }
        }

        return mbd.resolveBeanClass(beanClassLoader);
    }

    protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
        if(this.beanExpressionResolver == null) {
            return value;
        } else {
            Scope scope = beanDefinition != null?this.getRegisteredScope(beanDefinition.getScope()):null;
            return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
        }
    }

    protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
        Class targetType = mbd.getTargetType();
        return targetType != null?targetType:(mbd.getFactoryMethodName() != null?null:this.resolveBeanClass(mbd, beanName, typesToMatch));
    }

    protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
        Class beanType = this.predictBeanType(beanName, mbd, new Class[]{FactoryBean.class});
        return beanType != null && FactoryBean.class.isAssignableFrom(beanType);
    }

    protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
        if(!mbd.isSingleton()) {
            return null;
        } else {
            try {
                FactoryBean ex = (FactoryBean)this.doGetBean("&" + beanName, FactoryBean.class, (Object[])null, true);
                return this.getTypeForFactoryBean(ex);
            } catch (BeanCreationException var4) {
                if(var4 instanceof BeanCurrentlyInCreationException) {
                    if(this.logger.isDebugEnabled()) {
                        this.logger.debug("Bean currently in creation on FactoryBean type check: " + var4);
                    }
                } else if(mbd.isLazyInit()) {
                    if(this.logger.isDebugEnabled()) {
                        this.logger.debug("Bean creation exception on lazy FactoryBean type check: " + var4);
                    }
                } else if(this.logger.isWarnEnabled()) {
                    this.logger.warn("Bean creation exception on non-lazy FactoryBean type check: " + var4);
                }

                this.onSuppressedException(var4);
                return null;
            }
        }
    }

    protected void markBeanAsCreated(String beanName) {
        if(!this.alreadyCreated.contains(beanName)) {
            Map var2 = this.mergedBeanDefinitions;
            synchronized(this.mergedBeanDefinitions) {
                if(!this.alreadyCreated.contains(beanName)) {
                    this.clearMergedBeanDefinition(beanName);
                    this.alreadyCreated.add(beanName);
                }
            }
        }

    }

    protected void cleanupAfterBeanCreationFailure(String beanName) {
        Map var2 = this.mergedBeanDefinitions;
        synchronized(this.mergedBeanDefinitions) {
            this.alreadyCreated.remove(beanName);
        }
    }

    protected boolean isBeanEligibleForMetadataCaching(String beanName) {
        return this.alreadyCreated.contains(beanName);
    }

    protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
        if(!this.alreadyCreated.contains(beanName)) {
            this.removeSingleton(beanName);
            return true;
        } else {
            return false;
        }
    }

    protected boolean hasBeanCreationStarted() {
        return !this.alreadyCreated.isEmpty();
    }

    protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
        if(BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
            throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
        } else if(beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
            Object object = null;
            if(mbd == null) {
                object = this.getCachedObjectForFactoryBean(beanName);
            }

            if(object == null) {
                FactoryBean factory = (FactoryBean)beanInstance;
                if(mbd == null && this.containsBeanDefinition(beanName)) {
                    mbd = this.getMergedLocalBeanDefinition(beanName);
                }

                boolean synthetic = mbd != null && mbd.isSynthetic();
                object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
            }

            return object;
        } else {
            return beanInstance;
        }
    }

    public boolean isBeanNameInUse(String beanName) {
        return this.isAlias(beanName) || this.containsLocalBean(beanName) || this.hasDependentBean(beanName);
    }

    protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
        return bean != null && (DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || this.hasDestructionAwareBeanPostProcessors() && DisposableBeanAdapter.hasApplicableProcessors(bean, this.getBeanPostProcessors()));
    }

    protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
        AccessControlContext acc = System.getSecurityManager() != null?this.getAccessControlContext():null;
        if(!mbd.isPrototype() && this.requiresDestruction(bean, mbd)) {
            if(mbd.isSingleton()) {
                this.registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
            } else {
                Scope scope = (Scope)this.scopes.get(mbd.getScope());
                if(scope == null) {
                    throw new IllegalStateException("No Scope registered for scope name \'" + mbd.getScope() + "\'");
                }

                scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, this.getBeanPostProcessors(), acc));
            }
        }

    }

    protected abstract boolean containsBeanDefinition(String var1);

    protected abstract BeanDefinition getBeanDefinition(String var1) throws BeansException;

    protected abstract Object createBean(String var1, RootBeanDefinition var2, Object[] var3) throws BeanCreationException;
}

十二、AutowireCapableBeanFactory 基於註解的beanFactory接口

public interface AutowireCapableBeanFactory extends BeanFactory {
    int AUTOWIRE_NO = 0;
    int AUTOWIRE_BY_NAME = 1;
    int AUTOWIRE_BY_TYPE = 2;
    int AUTOWIRE_CONSTRUCTOR = 3;
    /** @deprecated */
    @Deprecated
    int AUTOWIRE_AUTODETECT = 4;

    <T> T createBean(Class<T> var1) throws BeansException;

    void autowireBean(Object var1) throws BeansException;

    Object configureBean(Object var1, String var2) throws BeansException;

    Object createBean(Class<?> var1, int var2, boolean var3) throws BeansException;

    Object autowire(Class<?> var1, int var2, boolean var3) throws BeansException;

    void autowireBeanProperties(Object var1, int var2, boolean var3) throws BeansException;

    void applyBeanPropertyValues(Object var1, String var2) throws BeansException;

    Object initializeBean(Object var1, String var2) throws BeansException;

    Object applyBeanPostProcessorsBeforeInitialization(Object var1, String var2) throws BeansException;

    Object applyBeanPostProcessorsAfterInitialization(Object var1, String var2) throws BeansException;

    void destroyBean(Object var1);

    <T> NamedBeanHolder<T> resolveNamedBean(Class<T> var1) throws BeansException;

    Object resolveDependency(DependencyDescriptor var1, String var2) throws BeansException;

    Object resolveDependency(DependencyDescriptor var1, String var2, Set<String> var3, TypeConverter var4) throws BeansException;
}

1三、AbstractAutowireCapableBeanFactory 註解beanFactory實現類(抽象類)

extends AbstractBeanFactory implements AutowireCapableBeanFactory

繼承了抽象beanFacotory繼承註解工廠接口

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
    private InstantiationStrategy instantiationStrategy;
    private ParameterNameDiscoverer parameterNameDiscoverer;
    private boolean allowCircularReferences;
    private boolean allowRawInjectionDespiteWrapping;
    private final Set<Class<?>> ignoredDependencyTypes;
    private final Set<Class<?>> ignoredDependencyInterfaces;
    private final Map<String, BeanWrapper> factoryBeanInstanceCache;
    private final ConcurrentMap<Class<?>, PropertyDescriptor[]> filteredPropertyDescriptorsCache;

    public AbstractAutowireCapableBeanFactory() {
        this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();
        this.parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
        this.allowCircularReferences = true;
        this.allowRawInjectionDespiteWrapping = false;
        this.ignoredDependencyTypes = new HashSet();
        this.ignoredDependencyInterfaces = new HashSet();
        this.factoryBeanInstanceCache = new ConcurrentHashMap(16);
        this.filteredPropertyDescriptorsCache = new ConcurrentHashMap(256);
        this.ignoreDependencyInterface(BeanNameAware.class);
        this.ignoreDependencyInterface(BeanFactoryAware.class);
        this.ignoreDependencyInterface(BeanClassLoaderAware.class);
    }

    public AbstractAutowireCapableBeanFactory(BeanFactory parentBeanFactory) {
        this();
        this.setParentBeanFactory(parentBeanFactory);
    }

    public void setInstantiationStrategy(InstantiationStrategy instantiationStrategy) {
        this.instantiationStrategy = instantiationStrategy;
    }

    protected InstantiationStrategy getInstantiationStrategy() {
        return this.instantiationStrategy;
    }

    public void setParameterNameDiscoverer(ParameterNameDiscoverer parameterNameDiscoverer) {
        this.parameterNameDiscoverer = parameterNameDiscoverer;
    }

    protected ParameterNameDiscoverer getParameterNameDiscoverer() {
        return this.parameterNameDiscoverer;
    }

    public void setAllowCircularReferences(boolean allowCircularReferences) {
        this.allowCircularReferences = allowCircularReferences;
    }

    public void setAllowRawInjectionDespiteWrapping(boolean allowRawInjectionDespiteWrapping) {
        this.allowRawInjectionDespiteWrapping = allowRawInjectionDespiteWrapping;
    }

    public void ignoreDependencyType(Class<?> type) {
        this.ignoredDependencyTypes.add(type);
    }

    public void ignoreDependencyInterface(Class<?> ifc) {
        this.ignoredDependencyInterfaces.add(ifc);
    }

    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if(otherFactory instanceof AbstractAutowireCapableBeanFactory) {
            AbstractAutowireCapableBeanFactory otherAutowireFactory = (AbstractAutowireCapableBeanFactory)otherFactory;
            this.instantiationStrategy = otherAutowireFactory.instantiationStrategy;
            this.allowCircularReferences = otherAutowireFactory.allowCircularReferences;
            this.ignoredDependencyTypes.addAll(otherAutowireFactory.ignoredDependencyTypes);
            this.ignoredDependencyInterfaces.addAll(otherAutowireFactory.ignoredDependencyInterfaces);
        }

    }

    public <T> T createBean(Class<T> beanClass) throws BeansException {
        RootBeanDefinition bd = new RootBeanDefinition(beanClass);
        bd.setScope("prototype");
        bd.allowCaching = ClassUtils.isCacheSafe(beanClass, this.getBeanClassLoader());
        return this.createBean(beanClass.getName(), bd, (Object[])null);
    }

    public void autowireBean(Object existingBean) {
        RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean));
        bd.setScope("prototype");
        bd.allowCaching = ClassUtils.isCacheSafe(bd.getBeanClass(), this.getBeanClassLoader());
        BeanWrapperImpl bw = new BeanWrapperImpl(existingBean);
        this.initBeanWrapper(bw);
        this.populateBean(bd.getBeanClass().getName(), bd, bw);
    }

    public Object configureBean(Object existingBean, String beanName) throws BeansException {
        this.markBeanAsCreated(beanName);
        BeanDefinition mbd = this.getMergedBeanDefinition(beanName);
        RootBeanDefinition bd = null;
        if(mbd instanceof RootBeanDefinition) {
            RootBeanDefinition bw = (RootBeanDefinition)mbd;
            bd = bw.isPrototype()?bw:bw.cloneBeanDefinition();
        }

        if(!mbd.isPrototype()) {
            if(bd == null) {
                bd = new RootBeanDefinition(mbd);
            }

            bd.setScope("prototype");
            bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), this.getBeanClassLoader());
        }

        BeanWrapperImpl bw1 = new BeanWrapperImpl(existingBean);
        this.initBeanWrapper(bw1);
        this.populateBean(beanName, bd, bw1);
        return this.initializeBean(beanName, existingBean, bd);
    }

    public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException {
        return this.resolveDependency(descriptor, requestingBeanName, (Set)null, (TypeConverter)null);
    }

    public Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
        RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
        bd.setScope("prototype");
        return this.createBean(beanClass.getName(), bd, (Object[])null);
    }

    public Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException {
        final RootBeanDefinition bd = new RootBeanDefinition(beanClass, autowireMode, dependencyCheck);
        bd.setScope("prototype");
        if(bd.getResolvedAutowireMode() == 3) {
            return this.autowireConstructor(beanClass.getName(), bd, (Constructor[])null, (Object[])null).getWrappedInstance();
        } else {
            Object bean;
            if(System.getSecurityManager() != null) {
                bean = AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(bd, (String)null, AbstractAutowireCapableBeanFactory.this);
                    }
                }, this.getAccessControlContext());
            } else {
                bean = this.getInstantiationStrategy().instantiate(bd, (String)null, this);
            }

            this.populateBean(beanClass.getName(), bd, new BeanWrapperImpl(bean));
            return bean;
        }
    }

    public void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck) throws BeansException {
        if(autowireMode == 3) {
            throw new IllegalArgumentException("AUTOWIRE_CONSTRUCTOR not supported for existing bean instance");
        } else {
            RootBeanDefinition bd = new RootBeanDefinition(ClassUtils.getUserClass(existingBean), autowireMode, dependencyCheck);
            bd.setScope("prototype");
            BeanWrapperImpl bw = new BeanWrapperImpl(existingBean);
            this.initBeanWrapper(bw);
            this.populateBean(bd.getBeanClass().getName(), bd, bw);
        }
    }

    public void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException {
        this.markBeanAsCreated(beanName);
        BeanDefinition bd = this.getMergedBeanDefinition(beanName);
        BeanWrapperImpl bw = new BeanWrapperImpl(existingBean);
        this.initBeanWrapper(bw);
        this.applyPropertyValues(beanName, bd, bw, bd.getPropertyValues());
    }

    public Object initializeBean(Object existingBean, String beanName) {
        return this.initializeBean(beanName, existingBean, (RootBeanDefinition)null);
    }

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if(!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessBeforeInitialization(result, beanName);
        } while(result != null);

        return result;
    }

    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;
        Iterator var4 = this.getBeanPostProcessors().iterator();

        do {
            if(!var4.hasNext()) {
                return result;
            }

            BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
            result = beanProcessor.postProcessAfterInitialization(result, beanName);
        } while(result != null);

        return result;
    }

    public void destroyBean(Object existingBean) {
        (new DisposableBeanAdapter(existingBean, this.getBeanPostProcessors(), this.getAccessControlContext())).destroy();
    }

    protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Creating instance of bean \'" + beanName + "\'");
        }

        RootBeanDefinition mbdToUse = mbd;
        Class resolvedClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        if(resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        try {
            mbdToUse.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException var7) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", var7);
        }

        Object beanInstance;
        try {
            beanInstance = this.resolveBeforeInstantiation(beanName, mbdToUse);
            if(beanInstance != null) {
                return beanInstance;
            }
        } catch (Throwable var8) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var8);
        }

        beanInstance = this.doCreateBean(beanName, mbdToUse, args);
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Finished creating instance of bean \'" + beanName + "\'");
        }

        return beanInstance;
    }

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if(mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }

        if(instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
        Class beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
        mbd.resolvedTargetType = beanType;
        Object earlySingletonExposure = mbd.postProcessingLock;
        synchronized(mbd.postProcessingLock) {
            if(!mbd.postProcessed) {
                try {
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }

        boolean var20 = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
        if(var20) {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Eagerly caching bean \'" + beanName + "\' to allow for resolving potential circular references");
            }

            this.addSingletonFactory(beanName, new ObjectFactory() {
                public Object getObject() throws BeansException {
                    return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }

        Object exposedObject = bean;

        try {
            this.populateBean(beanName, mbd, instanceWrapper);
            if(exposedObject != null) {
                exposedObject = this.initializeBean(beanName, exposedObject, mbd);
            }
        } catch (Throwable var18) {
            if(var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {
                throw (BeanCreationException)var18;
            }

            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);
        }

        if(var20) {
            Object ex = this.getSingleton(beanName, false);
            if(ex != null) {
                if(exposedObject == bean) {
                    exposedObject = ex;
                } else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
                    String[] dependentBeans = this.getDependentBeans(beanName);
                    LinkedHashSet actualDependentBeans = new LinkedHashSet(dependentBeans.length);
                    String[] var12 = dependentBeans;
                    int var13 = dependentBeans.length;

                    for(int var14 = 0; var14 < var13; ++var14) {
                        String dependentBean = var12[var14];
                        if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }

                    if(!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName, "Bean with name \'" + beanName + "\' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using \'getBeanNamesOfType\' with the \'allowEagerInit\' flag turned off, for example.");
                    }
                }
            }
        }

        try {
            this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
            return exposedObject;
        } catch (BeanDefinitionValidationException var16) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
        }
    }

    protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
        Class targetType = this.determineTargetType(beanName, mbd, typesToMatch);
        if(targetType != null && !mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
            Iterator var5 = this.getBeanPostProcessors().iterator();

            while(var5.hasNext()) {
                BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                if(bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
                    Class predicted = ibp.predictBeanType(targetType, beanName);
                    if(predicted != null && (typesToMatch.length != 1 || FactoryBean.class != typesToMatch[0] || FactoryBean.class.isAssignableFrom(predicted))) {
                        return predicted;
                    }
                }
            }
        }

        return targetType;
    }

    protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
        Class targetType = mbd.getTargetType();
        if(targetType == null) {
            targetType = mbd.getFactoryMethodName() != null?this.getTypeForFactoryMethod(beanName, mbd, typesToMatch):this.resolveBeanClass(mbd, beanName, typesToMatch);
            if(ObjectUtils.isEmpty(typesToMatch) || this.getTempClassLoader() == null) {
                mbd.resolvedTargetType = targetType;
            }
        }

        return targetType;
    }

    protected Class<?> getTypeForFactoryMethod(String beanName, RootBeanDefinition mbd, Class... typesToMatch) {
        ResolvableType cachedReturnType = mbd.factoryMethodReturnType;
        if(cachedReturnType != null) {
            return cachedReturnType.resolve();
        } else {
            boolean isStatic = true;
            String factoryBeanName = mbd.getFactoryBeanName();
            Class factoryClass;
            if(factoryBeanName != null) {
                if(factoryBeanName.equals(beanName)) {
                    throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "factory-bean reference points back to the same bean definition");
                }

                factoryClass = this.getType(factoryBeanName);
                isStatic = false;
            } else {
                factoryClass = this.resolveBeanClass(mbd, beanName, typesToMatch);
            }

            if(factoryClass == null) {
                return null;
            } else {
                factoryClass = ClassUtils.getUserClass(factoryClass);
                Class commonType = null;
                Method uniqueCandidate = null;
                int minNrOfArgs = mbd.getConstructorArgumentValues().getArgumentCount();
                Method[] candidates = ReflectionUtils.getUniqueDeclaredMethods(factoryClass);
                Method[] var12 = candidates;
                int var13 = candidates.length;

                for(int var14 = 0; var14 < var13; ++var14) {
                    Method factoryMethod = var12[var14];
                    if(Modifier.isStatic(factoryMethod.getModifiers()) == isStatic && factoryMethod.getName().equals(mbd.getFactoryMethodName()) && factoryMethod.getParameterTypes().length >= minNrOfArgs) {
                        if(factoryMethod.getTypeParameters().length > 0) {
                            try {
                                Class[] ex = factoryMethod.getParameterTypes();
                                String[] paramNames = null;
                                ParameterNameDiscoverer pnd = this.getParameterNameDiscoverer();
                                if(pnd != null) {
                                    paramNames = pnd.getParameterNames(factoryMethod);
                                }

                                ConstructorArgumentValues cav = mbd.getConstructorArgumentValues();
                                HashSet usedValueHolders = new HashSet(ex.length);
                                Object[] args = new Object[ex.length];

                                for(int returnType = 0; returnType < args.length; ++returnType) {
                                    ValueHolder valueHolder = cav.getArgumentValue(returnType, ex[returnType], paramNames != null?paramNames[returnType]:null, usedValueHolders);
                                    if(valueHolder == null) {
                                        valueHolder = cav.getGenericArgumentValue((Class)null, (String)null, usedValueHolders);
                                    }

                                    if(valueHolder != null) {
                                        args[returnType] = valueHolder.getValue();
                                        usedValueHolders.add(valueHolder);
                                    }
                                }

                                Class var25 = AutowireUtils.resolveReturnTypeForFactoryMethod(factoryMethod, args, this.getBeanClassLoader());
                                if(var25 != null) {
                                    uniqueCandidate = commonType == null?factoryMethod:null;
                                    commonType = ClassUtils.determineCommonAncestor(var25, commonType);
                                    if(commonType == null) {
                                        return null;
                                    }
                                }
                            } catch (Throwable var24) {
                                if(this.logger.isDebugEnabled()) {
                                    this.logger.debug("Failed to resolve generic return type for factory method: " + var24);
                                }
                            }
                        } else {
                            uniqueCandidate = commonType == null?factoryMethod:null;
                            commonType = ClassUtils.determineCommonAncestor(factoryMethod.getReturnType(), commonType);
                            if(commonType == null) {
                                return null;
                            }
                        }
                    }
                }

                if(commonType != null) {
                    mbd.factoryMethodReturnType = uniqueCandidate != null?ResolvableType.forMethodReturnType(uniqueCandidate):ResolvableType.forClass(commonType);
                }

                return commonType;
            }
        }
    }

    protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
        String factoryBeanName = mbd.getFactoryBeanName();
        String factoryMethodName = mbd.getFactoryMethodName();
        if(factoryBeanName != null) {
            if(factoryMethodName != null) {
                BeanDefinition fb = this.getBeanDefinition(factoryBeanName);
                if(fb instanceof AbstractBeanDefinition) {
                    AbstractBeanDefinition result = (AbstractBeanDefinition)fb;
                    if(result.hasBeanClass()) {
                        Class result1 = this.getTypeForFactoryBeanFromMethod(result.getBeanClass(), factoryMethodName);
                        if(result1 != null) {
                            return result1;
                        }
                    }
                }
            }

            if(!this.isBeanEligibleForMetadataCaching(factoryBeanName)) {
                return null;
            }
        }

        FactoryBean fb1 = mbd.isSingleton()?this.getSingletonFactoryBeanForTypeCheck(beanName, mbd):this.getNonSingletonFactoryBeanForTypeCheck(beanName, mbd);
        if(fb1 != null) {
            Class result2 = this.getTypeForFactoryBean(fb1);
            return result2 != null?result2:super.getTypeForFactoryBean(beanName, mbd);
        } else {
            return factoryBeanName == null && mbd.hasBeanClass()?(factoryMethodName != null?this.getTypeForFactoryBeanFromMethod(mbd.getBeanClass(), factoryMethodName):GenericTypeResolver.resolveTypeArgument(mbd.getBeanClass(), FactoryBean.class)):null;
        }
    }

    private Class<?> getTypeForFactoryBeanFromMethod(Class<?> beanClass, final String factoryMethodName) {
        class Holder {
            Class<?> value = null;

            Holder() {
            }
        }

        final Holder objectType = new Holder();
        Class fbClass = ClassUtils.getUserClass(beanClass);
        ReflectionUtils.doWithMethods(fbClass, new MethodCallback() {
            public void doWith(Method method) {
                if(method.getName().equals(factoryMethodName) && FactoryBean.class.isAssignableFrom(method.getReturnType())) {
                    Class currentType = GenericTypeResolver.resolveReturnTypeArgument(method, FactoryBean.class);
                    if(currentType != null) {
                        objectType.value = ClassUtils.determineCommonAncestor(currentType, objectType.value);
                    }
                }

            }
        });
        return objectType.value != null && Object.class != objectType.value?objectType.value:null;
    }

    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
        Object exposedObject = bean;
        if(bean != null && !mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
            Iterator var5 = this.getBeanPostProcessors().iterator();

            while(var5.hasNext()) {
                BeanPostProcessor bp = (BeanPostProcessor)var5.next();
                if(bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
                    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
                    if(exposedObject == null) {
                        return null;
                    }
                }
            }
        }

        return exposedObject;
    }

    private FactoryBean<?> getSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
        synchronized(this.getSingletonMutex()) {
            BeanWrapper bw = (BeanWrapper)this.factoryBeanInstanceCache.get(beanName);
            if(bw != null) {
                return (FactoryBean)bw.getWrappedInstance();
            } else if(!this.isSingletonCurrentlyInCreation(beanName) && (mbd.getFactoryBeanName() == null || !this.isSingletonCurrentlyInCreation(mbd.getFactoryBeanName()))) {
                Object instance = null;

                try {
                    this.beforeSingletonCreation(beanName);
                    instance = this.resolveBeforeInstantiation(beanName, mbd);
                    if(instance == null) {
                        bw = this.createBeanInstance(beanName, mbd, (Object[])null);
                        instance = bw.getWrappedInstance();
                    }
                } finally {
                    this.afterSingletonCreation(beanName);
                }

                FactoryBean fb = this.getFactoryBean(beanName, instance);
                if(bw != null) {
                    this.factoryBeanInstanceCache.put(beanName, bw);
                }

                return fb;
            } else {
                return null;
            }
        }
    }

    private FactoryBean<?> getNonSingletonFactoryBeanForTypeCheck(String beanName, RootBeanDefinition mbd) {
        if(this.isPrototypeCurrentlyInCreation(beanName)) {
            return null;
        } else {
            Object instance = null;

            Object var5;
            try {
                this.beforePrototypeCreation(beanName);
                instance = this.resolveBeforeInstantiation(beanName, mbd);
                if(instance == null) {
                    BeanWrapper ex = this.createBeanInstance(beanName, mbd, (Object[])null);
                    instance = ex.getWrappedInstance();
                }

                return this.getFactoryBean(beanName, instance);
            } catch (BeanCreationException var9) {
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Bean creation exception on non-singleton FactoryBean type check: " + var9);
                }

                this.onSuppressedException(var9);
                var5 = null;
            } finally {
                this.afterPrototypeCreation(beanName);
            }

            return (FactoryBean)var5;
        }
    }

    protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
        Iterator var4 = this.getBeanPostProcessors().iterator();

        while(var4.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var4.next();
            if(bp instanceof MergedBeanDefinitionPostProcessor) {
                MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor)bp;
                bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
            }
        }

    }

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Class targetType = this.determineTargetType(beanName, mbd, new Class[0]);
                if(targetType != null) {
                    bean = this.applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if(bean != null) {
                        bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }

            mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
        }

        return bean;
    }

    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        Iterator var3 = this.getBeanPostProcessors().iterator();

        while(var3.hasNext()) {
            BeanPostProcessor bp = (BeanPostProcessor)var3.next();
            if(bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if(result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
        Class beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
        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());
        } else if(mbd.getFactoryMethodName() != null) {
            return this.instantiateUsingFactoryMethod(beanName, mbd, args);
        } else {
            boolean resolved = false;
            boolean autowireNecessary = false;
            if(args == null) {
                Object ctors = mbd.constructorArgumentLock;
                synchronized(mbd.constructorArgumentLock) {
                    if(mbd.resolvedConstructorOrFactoryMethod != null) {
                        resolved = true;
                        autowireNecessary = mbd.constructorArgumentsResolved;
                    }
                }
            }

            if(resolved) {
                return autowireNecessary?this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null):this.instantiateBean(beanName, mbd);
            } else {
                Constructor[] ctors1 = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
                return ctors1 == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this.instantiateBean(beanName, mbd):this.autowireConstructor(beanName, mbd, ctors1, args);
            }
        }
    }

    protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(Class<?> beanClass, String beanName) throws BeansException {
        if(beanClass != null && this.hasInstantiationAwareBeanPostProcessors()) {
            Iterator var3 = this.getBeanPostProcessors().iterator();

            while(var3.hasNext()) {
                BeanPostProcessor bp = (BeanPostProcessor)var3.next();
                if(bp instanceof SmartInstantiationAwareBeanPostProcessor) {
                    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor)bp;
                    Constructor[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
                    if(ctors != null) {
                        return ctors;
                    }
                }
            }
        }

        return null;
    }

    protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
        try {
            Object ex;
            if(System.getSecurityManager() != null) {
                ex = AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.this);
                    }
                }, this.getAccessControlContext());
            } else {
                ex = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
            }

            BeanWrapperImpl bw = new BeanWrapperImpl(ex);
            this.initBeanWrapper(bw);
            return bw;
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
        }
    }

    protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
        return (new ConstructorResolver(this)).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
    }

    protected BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] ctors, Object[] explicitArgs) {
        return (new ConstructorResolver(this)).autowireConstructor(beanName, mbd, ctors, explicitArgs);
    }

    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        Object pvs = mbd.getPropertyValues();
        if(bw == null) {
            if(!((PropertyValues)pvs).isEmpty()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
        } else {
            boolean continueWithPropertyPopulation = true;
            if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
                Iterator hasInstAwareBpps = this.getBeanPostProcessors().iterator();

                while(hasInstAwareBpps.hasNext()) {
                    BeanPostProcessor needsDepCheck = (BeanPostProcessor)hasInstAwareBpps.next();
                    if(needsDepCheck instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor filteredPds = (InstantiationAwareBeanPostProcessor)needsDepCheck;
                        if(!filteredPds.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                            continueWithPropertyPopulation = false;
                            break;
                        }
                    }
                }
            }

            if(continueWithPropertyPopulation) {
                if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
                    MutablePropertyValues hasInstAwareBpps1 = new MutablePropertyValues((PropertyValues)pvs);
                    if(mbd.getResolvedAutowireMode() == 1) {
                        this.autowireByName(beanName, mbd, bw, hasInstAwareBpps1);
                    }

                    if(mbd.getResolvedAutowireMode() == 2) {
                        this.autowireByType(beanName, mbd, bw, hasInstAwareBpps1);
                    }

                    pvs = hasInstAwareBpps1;
                }

                boolean hasInstAwareBpps2 = this.hasInstantiationAwareBeanPostProcessors();
                boolean needsDepCheck1 = mbd.getDependencyCheck() != 0;
                if(hasInstAwareBpps2 || needsDepCheck1) {
                    PropertyDescriptor[] filteredPds1 = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    if(hasInstAwareBpps2) {
                        Iterator var9 = this.getBeanPostProcessors().iterator();

                        while(var9.hasNext()) {
                            BeanPostProcessor bp = (BeanPostProcessor)var9.next();
                            if(bp instanceof InstantiationAwareBeanPostProcessor) {
                                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
                                pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds1, bw.getWrappedInstance(), beanName);
                                if(pvs == null) {
                                    return;
                                }
                            }
                        }
                    }

                    if(needsDepCheck1) {
                        this.checkDependencies(beanName, mbd, filteredPds1, (PropertyValues)pvs);
                    }
                }

                this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
            }
        }
    }

    protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw);
        String[] var6 = propertyNames;
        int var7 = propertyNames.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            String propertyName = var6[var8];
            if(this.containsBean(propertyName)) {
                Object bean = this.getBean(propertyName);
                pvs.add(propertyName, bean);
                this.registerDependentBean(propertyName, beanName);
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Added autowiring by name from bean name \'" + beanName + "\' via property \'" + propertyName + "\' to bean named \'" + propertyName + "\'");
                }
            } else if(this.logger.isTraceEnabled()) {
                this.logger.trace("Not autowiring property \'" + propertyName + "\' of bean \'" + beanName + "\' by name: no matching bean found");
            }
        }

    }

    protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
        Object converter = this.getCustomTypeConverter();
        if(converter == null) {
            converter = bw;
        }

        LinkedHashSet autowiredBeanNames = new LinkedHashSet(4);
        String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw);
        String[] var8 = propertyNames;
        int var9 = propertyNames.length;

        for(int var10 = 0; var10 < var9; ++var10) {
            String propertyName = var8[var10];

            try {
                PropertyDescriptor ex = bw.getPropertyDescriptor(propertyName);
                if(Object.class != ex.getPropertyType()) {
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(ex);
                    boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
                    AbstractAutowireCapableBeanFactory.AutowireByTypeDependencyDescriptor desc = new AbstractAutowireCapableBeanFactory.AutowireByTypeDependencyDescriptor(methodParam, eager);
                    Object autowiredArgument = this.resolveDependency(desc, beanName, autowiredBeanNames, (TypeConverter)converter);
                    if(autowiredArgument != null) {
                        pvs.add(propertyName, autowiredArgument);
                    }

                    Iterator var17 = autowiredBeanNames.iterator();

                    while(var17.hasNext()) {
                        String autowiredBeanName = (String)var17.next();
                        this.registerDependentBean(autowiredBeanName, beanName);
                        if(this.logger.isDebugEnabled()) {
                            this.logger.debug("Autowiring by type from bean name \'" + beanName + "\' via property \'" + propertyName + "\' to bean named \'" + autowiredBeanName + "\'");
                        }
                    }

                    autowiredBeanNames.clear();
                }
            } catch (BeansException var19) {
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, var19);
            }
        }

    }

    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
        TreeSet result = new TreeSet();
        MutablePropertyValues pvs = mbd.getPropertyValues();
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
        PropertyDescriptor[] var6 = pds;
        int var7 = pds.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            PropertyDescriptor pd = var6[var8];
            if(pd.getWriteMethod() != null && !this.isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) && !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                result.add(pd.getName());
            }
        }

        return StringUtils.toStringArray(result);
    }

    protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw, boolean cache) {
        PropertyDescriptor[] filtered = (PropertyDescriptor[])this.filteredPropertyDescriptorsCache.get(bw.getWrappedClass());
        if(filtered == null) {
            filtered = this.filterPropertyDescriptorsForDependencyCheck(bw);
            if(cache) {
                PropertyDescriptor[] existing = (PropertyDescriptor[])this.filteredPropertyDescriptorsCache.putIfAbsent(bw.getWrappedClass(), filtered);
                if(existing != null) {
                    filtered = existing;
                }
            }
        }

        return filtered;
    }

    protected PropertyDescriptor[] filterPropertyDescriptorsForDependencyCheck(BeanWrapper bw) {
        LinkedList pds = new LinkedList(Arrays.asList(bw.getPropertyDescriptors()));
        Iterator it = pds.iterator();

        while(it.hasNext()) {
            PropertyDescriptor pd = (PropertyDescriptor)it.next();
            if(this.isExcludedFromDependencyCheck(pd)) {
                it.remove();
            }
        }

        return (PropertyDescriptor[])pds.toArray(new PropertyDescriptor[pds.size()]);
    }

    protected boolean isExcludedFromDependencyCheck(PropertyDescriptor pd) {
        return AutowireUtils.isExcludedFromDependencyCheck(pd) || this.ignoredDependencyTypes.contains(pd.getPropertyType()) || AutowireUtils.isSetterDefinedInInterface(pd, this.ignoredDependencyInterfaces);
    }

    protected void checkDependencies(String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, PropertyValues pvs) throws UnsatisfiedDependencyException {
        int dependencyCheck = mbd.getDependencyCheck();
        PropertyDescriptor[] var6 = pds;
        int var7 = pds.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            PropertyDescriptor pd = var6[var8];
            if(pd.getWriteMethod() != null && !pvs.contains(pd.getName())) {
                boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
                boolean unsatisfied = dependencyCheck == 3 || isSimple && dependencyCheck == 2 || !isSimple && dependencyCheck == 1;
                if(unsatisfied) {
                    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(), "Set this property value or disable dependency checking for this bean.");
                }
            }
        }

    }

    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if(pvs != null && !pvs.isEmpty()) {
            MutablePropertyValues mpvs = null;
            if(System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
                ((BeanWrapperImpl)bw).setSecurityContext(this.getAccessControlContext());
            }

            List original;
            if(pvs instanceof MutablePropertyValues) {
                mpvs = (MutablePropertyValues)pvs;
                if(mpvs.isConverted()) {
                    try {
                        bw.setPropertyValues(mpvs);
                        return;
                    } catch (BeansException var18) {
                        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var18);
                    }
                }

                original = mpvs.getPropertyValueList();
            } else {
                original = Arrays.asList(pvs.getPropertyValues());
            }

            Object converter = this.getCustomTypeConverter();
            if(converter == null) {
                converter = bw;
            }

            BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, (TypeConverter)converter);
            ArrayList deepCopy = new ArrayList(original.size());
            boolean resolveNecessary = false;
            Iterator ex = original.iterator();

            while(true) {
                while(ex.hasNext()) {
                    PropertyValue pv = (PropertyValue)ex.next();
                    if(pv.isConverted()) {
                        deepCopy.add(pv);
                    } else {
                        String propertyName = pv.getName();
                        Object originalValue = pv.getValue();
                        Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                        Object convertedValue = resolvedValue;
                        boolean convertible = bw.isWritableProperty(propertyName) && !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                        if(convertible) {
                            convertedValue = this.convertForProperty(resolvedValue, propertyName, bw, (TypeConverter)converter);
                        }

                        if(resolvedValue == originalValue) {
                            if(convertible) {
                                pv.setConvertedValue(convertedValue);
                            }

                            deepCopy.add(pv);
                        } else if(convertible && originalValue instanceof TypedStringValue && !((TypedStringValue)originalValue).isDynamic() && !(convertedValue instanceof Collection) && !ObjectUtils.isArray(convertedValue)) {
                            pv.setConvertedValue(convertedValue);
                            deepCopy.add(pv);
                        } else {
                            resolveNecessary = true;
                            deepCopy.add(new PropertyValue(pv, convertedValue));
                        }
                    }
                }

                if(mpvs != null && !resolveNecessary) {
                    mpvs.setConverted();
                }

                try {
                    bw.setPropertyValues(new MutablePropertyValues(deepCopy));
                    return;
                } catch (BeansException var19) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", var19);
                }
            }
        }
    }

    private Object convertForProperty(Object value, String propertyName, BeanWrapper bw, TypeConverter converter) {
        if(converter instanceof BeanWrapperImpl) {
            return ((BeanWrapperImpl)converter).convertForProperty(value, propertyName);
        } else {
            PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
            MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
            return converter.convertIfNecessary(value, pd.getPropertyType(), methodParam);
        }
    }

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if(System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if(mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", var6);
        }

        if(mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

    private void invokeAwareMethods(String beanName, Object bean) {
        if(bean instanceof Aware) {
            if(bean instanceof BeanNameAware) {
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            if(bean instanceof BeanClassLoaderAware) {
                ((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
            }

            if(bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware)bean).setBeanFactory(this);
            }
        }

    }

    protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
        boolean isInitializingBean = bean instanceof InitializingBean;
        if(isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Invoking afterPropertiesSet() on bean with name \'" + beanName + "\'");
            }

            if(System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            ((InitializingBean)bean).afterPropertiesSet();
                            return null;
                        }
                    }, this.getAccessControlContext());
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {
                ((InitializingBean)bean).afterPropertiesSet();
            }
        }

        if(mbd != null) {
            String initMethodName = mbd.getInitMethodName();
            if(initMethodName != null && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
                this.invokeCustomInitMethod(beanName, bean, mbd);
            }
        }

    }

    protected void invokeCustomInitMethod(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
        String initMethodName = mbd.getInitMethodName();
        final Method initMethod = mbd.isNonPublicAccessAllowed()?BeanUtils.findMethod(bean.getClass(), initMethodName, new Class[0]):ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName, new Class[0]);
        if(initMethod == null) {
            if(mbd.isEnforceInitMethod()) {
                throw new BeanDefinitionValidationException("Couldn\'t find an init method named \'" + initMethodName + "\' on bean with name \'" + beanName + "\'");
            } else {
                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("No default init method named \'" + initMethodName + "\' found on bean with name \'" + beanName + "\'");
                }

            }
        } else {
            if(this.logger.isDebugEnabled()) {
                this.logger.debug("Invoking init method  \'" + initMethodName + "\' on bean with name \'" + beanName + "\'");
            }

            if(System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedExceptionAction() {
                    public Object run() throws Exception {
                        ReflectionUtils.makeAccessible(initMethod);
                        return null;
                    }
                });

                try {
                    AccessController.doPrivileged(new PrivilegedExceptionAction() {
                        public Object run() throws Exception {
                            initMethod.invoke(bean, new Object[0]);
                            return null;
                        }
                    }, this.getAccessControlContext());
                } catch (PrivilegedActionException var9) {
                    InvocationTargetException ex = (InvocationTargetException)var9.getException();
                    throw ex.getTargetException();
                }
            } else {
                try {
                    ReflectionUtils.makeAccessible(initMethod);
                    initMethod.invoke(bean, new Object[0]);
                } catch (InvocationTargetException var8) {
                    throw var8.getTargetException();
                }
            }

        }
    }

    protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
        return this.applyBeanPostProcessorsAfterInitialization(object, beanName);
    }

    protected void removeSingleton(String beanName) {
        super.removeSingleton(beanName);
        this.factoryBeanInstanceCache.remove(beanName);
    }

    private static class AutowireByTypeDependencyDescriptor extends DependencyDescriptor {
        public AutowireByTypeDependencyDescriptor(MethodParameter methodParameter, boolean eager) {
            super(methodParameter, false, eager);
        }

        public String getDependencyName() {
            return null;
        }
    }
}

1四、ConfigurableListableBeanFactory 配置序列的beanFactory

public interface ConfigurableListableBeanFactory extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
    void ignoreDependencyType(Class<?> var1);

    void ignoreDependencyInterface(Class<?> var1);

    void registerResolvableDependency(Class<?> var1, Object var2);

    boolean isAutowireCandidate(String var1, DependencyDescriptor var2) throws NoSuchBeanDefinitionException;

    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    Iterator<String> getBeanNamesIterator();

    void clearMetadataCache();

    void freezeConfiguration();

    boolean isConfigurationFrozen();

    void preInstantiateSingletons() throws BeansException;
}

1五、DefaultListableBeanFactory 最終的實現類

extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable

繼承AbstractAutowireCapableBeanFactory

實現了ConfigurableListableBeanFactory、BeanDefinitionRegistrySerializable接口

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
    private static Class<?> javaUtilOptionalClass = null;
    private static Class<?> javaxInjectProviderClass = null;
    private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories;
    private String serializationId;
    private boolean allowBeanDefinitionOverriding = true;
    private boolean allowEagerClassLoading = true;
    private Comparator<Object> dependencyComparator;
    private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
    private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap(16);
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap(256);
    private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap(64);
    private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap(64);
    private volatile List<String> beanDefinitionNames = new ArrayList(256);
    private volatile Set<String> manualSingletonNames = new LinkedHashSet(16);
    private volatile String[] frozenBeanDefinitionNames;
    private volatile boolean configurationFrozen = false;

    public DefaultListableBeanFactory() {
    }

    public DefaultListableBeanFactory(BeanFactory parentBeanFactory) {
        super(parentBeanFactory);
    }

    public void setSerializationId(String serializationId) {
        if(serializationId != null) {
            serializableFactories.put(serializationId, new WeakReference(this));
        } else if(this.serializationId != null) {
            serializableFactories.remove(this.serializationId);
        }

        this.serializationId = serializationId;
    }

    public String getSerializationId() {
        return this.serializationId;
    }

    public void setAllowBeanDefinitionOverriding(boolean allowBeanDefinitionOverriding) {
        this.allowBeanDefinitionOverriding = allowBeanDefinitionOverriding;
    }

    public boolean isAllowBeanDefinitionOverriding() {
        return this.allowBeanDefinitionOverriding;
    }

    public void setAllowEagerClassLoading(boolean allowEagerClassLoading) {
        this.allowEagerClassLoading = allowEagerClassLoading;
    }

    public boolean isAllowEagerClassLoading() {
        return this.allowEagerClassLoading;
    }

    public void setDependencyComparator(Comparator<Object> dependencyComparator) {
        this.dependencyComparator = dependencyComparator;
    }

    public Comparator<Object> getDependencyComparator() {
        return this.dependencyComparator;
    }

    public void setAutowireCandidateResolver(final AutowireCandidateResolver autowireCandidateResolver) {
        Assert.notNull(autowireCandidateResolver, "AutowireCandidateResolver must not be null");
        if(autowireCandidateResolver instanceof BeanFactoryAware) {
            if(System.getSecurityManager() != null) {
                AccessController.doPrivileged(new PrivilegedAction() {
                    public Object run() {
                        ((BeanFactoryAware)autowireCandidateResolver).setBeanFactory(DefaultListableBeanFactory.this);
                        return null;
                    }
                }, this.getAccessControlContext());
            } else {
                ((BeanFactoryAware)autowireCandidateResolver).setBeanFactory(this);
            }
        }

        this.autowireCandidateResolver = autowireCandidateResolver;
    }

    public AutowireCandidateResolver getAutowireCandidateResolver() {
        return this.autowireCandidateResolver;
    }

    public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
        super.copyConfigurationFrom(otherFactory);
        if(otherFactory instanceof DefaultListableBeanFactory) {
            DefaultListableBeanFactory otherListableFactory = (DefaultListableBeanFactory)otherFactory;
            this.allowBeanDefinitionOverriding = otherListableFactory.allowBeanDefinitionOverriding;
            this.allowEagerClassLoading = otherListableFactory.allowEagerClassLoading;
            this.dependencyComparator = otherListableFactory.dependencyComparator;
            this.setAutowireCandidateResolver((AutowireCandidateResolver)BeanUtils.instantiateClass(this.getAutowireCandidateResolver().getClass()));
            this.resolvableDependencies.putAll(otherListableFactory.resolvableDependencies);
        }

    }

    public <T> T getBean(Class<T> requiredType) throws BeansException {
        return this.getBean(requiredType, (Object[])null);
    }

    public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
        NamedBeanHolder namedBean = this.resolveNamedBean(requiredType, args);
        if(namedBean != null) {
            return namedBean.getBeanInstance();
        } else {
            BeanFactory parent = this.getParentBeanFactory();
            if(parent != null) {
                return parent.getBean(requiredType, args);
            } else {
                throw new NoSuchBeanDefinitionException(requiredType);
            }
        }
    }

    public boolean containsBeanDefinition(String beanName) {
        Assert.notNull(beanName, "Bean name must not be null");
        return this.beanDefinitionMap.containsKey(beanName);
    }

    public int getBeanDefinitionCount() {
        return this.beanDefinitionMap.size();
    }

    public String[] getBeanDefinitionNames() {
        return this.frozenBeanDefinitionNames != null?(String[])this.frozenBeanDefinitionNames.clone():StringUtils.toStringArray(this.beanDefinitionNames);
    }

    public String[] getBeanNamesForType(ResolvableType type) {
        return this.doGetBeanNamesForType(type, true, true);
    }

    public String[] getBeanNamesForType(Class<?> type) {
        return this.getBeanNamesForType(type, true, true);
    }

    public String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
        if(this.isConfigurationFrozen() && type != null && allowEagerInit) {
            Map cache = includeNonSingletons?this.allBeanNamesByType:this.singletonBeanNamesByType;
            String[] resolvedBeanNames = (String[])cache.get(type);
            if(resolvedBeanNames != null) {
                return resolvedBeanNames;
            } else {
                resolvedBeanNames = this.doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
                if(ClassUtils.isCacheSafe(type, this.getBeanClassLoader())) {
                    cache.put(type, resolvedBeanNames);
                }

                return resolvedBeanNames;
            }
        } else {
            return this.doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
        }
    }

    private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
        ArrayList result = new ArrayList();
        Iterator var5 = this.beanDefinitionNames.iterator();

        while(true) {
            String beanName;
            do {
                if(!var5.hasNext()) {
                    var5 = this.manualSingletonNames.iterator();

                    while(var5.hasNext()) {
                        beanName = (String)var5.next();

                        try {
                            if(this.isFactoryBean(beanName)) {
                                if((includeNonSingletons || this.isSingleton(beanName)) && this.isTypeMatch(beanName, type)) {
                                    result.add(beanName);
                                    continue;
                                }

                                beanName = "&" + beanName;
                            }

                            if(this.isTypeMatch(beanName, type)) {
                                result.add(beanName);
                            }
                        } catch (NoSuchBeanDefinitionException var11) {
                            if(this.logger.isDebugEnabled()) {
                                this.logger.debug("Failed to check manually registered singleton with name \'" + beanName + "\'", var11);
                            }
                        }
                    }

                    return StringUtils.toStringArray(result);
                }

                beanName = (String)var5.next();
            } while(this.isAlias(beanName));

            try {
                RootBeanDefinition ex = this.getMergedLocalBeanDefinition(beanName);
                if(!ex.isAbstract() && (allowEagerInit || (ex.hasBeanClass() || !ex.isLazyInit() || this.isAllowEagerClassLoading()) && !this.requiresEagerInitForType(ex.getFactoryBeanName()))) {
                    boolean isFactoryBean;
                    boolean var10000;
                    label161: {
                        isFactoryBean = this.isFactoryBean(beanName, ex);
                        BeanDefinitionHolder dbd = ex.getDecoratedDefinition();
                        if(allowEagerInit || !isFactoryBean || dbd != null && !ex.isLazyInit() || this.containsSingleton(beanName)) {
                            label157: {
                                if(!includeNonSingletons) {
                                    if(dbd != null) {
                                        if(!ex.isSingleton()) {
                                            break label157;
                                        }
                                    } else if(!this.isSingleton(beanName)) {
                                        break label157;
                                    }
                                }

                                if(this.isTypeMatch(beanName, type)) {
                                    var10000 = true;
                                    break label161;
                                }
                            }
                        }

                        var10000 = false;
                    }

                    boolean matchFound = var10000;
                    if(!matchFound && isFactoryBean) {
                        beanName = "&" + beanName;
                        matchFound = (includeNonSingletons || ex.isSingleton()) && this.isTypeMatch(beanName, type);
                    }

                    if(matchFound) {
                        result.add(beanName);
                    }
                }
            } catch (CannotLoadBeanClassException var12) {
                if(allowEagerInit) {
                    throw var12;
                }

                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Ignoring bean class loading failure for bean \'" + beanName + "\'", var12);
                }

                this.onSuppressedException(var12);
            } catch (BeanDefinitionStoreException var13) {
                if(allowEagerInit) {
                    throw var13;
                }

                if(this.logger.isDebugEnabled()) {
                    this.logger.debug("Ignoring unresolvable metadata in bean definition \'" + beanName + "\'", var13);
                }

                this.onSuppressedException(var13);
            }
        }
    }

    private boolean requiresEagerInitForType(String factoryBeanName) {
        return factoryBeanName != null && this.isFactoryBean(factoryBeanName) && !this.containsSingleton(factoryBeanName);
    }

    public <T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException {
        return this.getBeansOfType(type, true, true);
    }

    public <T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) throws BeansException {
        String[] beanNames = this.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
        LinkedHashMap result = new LinkedHashMap(beanNames.length);
        String[] var6 = beanNames;
        int var7 = beanNames.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            String beanName = var6[var8];

            try {
                result.put(beanName, this.getBean(beanName, type));
            } catch (BeanCreationException var13) {
                Throwable rootCause = var13.getMostSpecificCause();
                if(rootCause instanceof BeanCurrentlyInCreationException) {
                    BeanCreationException bce = (BeanCreationException)rootCause;
                    if(this.isCurrentlyInCreation(bce.getBeanName())) {
                        if(this.logger.isDebugEnabled()) {
                            this.logger.debug("Ignoring match to currently created bean \'" + beanName + "\': " + var13.getMessage());
                        }

                        this.onSuppressedException(var13);
                        continue;
                    }
                }

                throw var13;
            }
        }

        return result;
    }

    public String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType) {
        ArrayList results = new ArrayList();
        Iterator var3 = this.beanDefinitionNames.iterator();

        String beanName;
        while(var3.hasNext()) {
            beanName = (String)var3.next();
            BeanDefinition beanDefinition = this.getBeanDefinition(beanName);
            if(!beanDefinition.isAbstract() && this.findAnnotationOnBean(beanName, annotationType) != null) {
                results.add(beanName);
            }
        }

        var3 = this.manualSingletonNames.iterator();

        while(var3.hasNext()) {
            beanName = (String)var3.next();
            if(!results.contains(beanName) && this.findAnnotationOnBean(beanName, annotationType) != null) {
                results.add(beanName);
            }
        }

        return (String[])results.toArray(new String[results.size()]);
    }

    public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) {
        String[] beanNames = this.getBeanNamesForAnnotation(annotationType);
        LinkedHashMap results = new LinkedHashMap(beanNames.length);
        String[] var4 = beanNames;
        int var5 = beanNames.length;

        for(int var6 = 0; var6 < var5; ++var6) {
            String beanName = var4[var6];
            results.put(beanName, this.getBean(beanName));
        }

        return results;
    }

    public <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException {
        Annotation ann = null;
        Class beanType = this.getType(beanName);
        if(beanType != null) {
            ann = AnnotationUtils.findAnnotation(beanType, annotationType);
        }

        if(ann == null && this.containsBeanDefinition(beanName)) {
            BeanDefinition bd = this.getMergedBeanDefinition(beanName);
            if(bd instanceof AbstractBeanDefinition) {
                AbstractBeanDefinition abd = (AbstractBeanDefinition)bd;
                if(abd.hasBeanClass()) {
                    ann = AnnotationUtils.findAnnotation(abd.getBeanClass(), annotationType);
                }
            }
        }

        return ann;
    }

    public void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue) {
        Assert.notNull(dependencyType, "Dependency type must not be null");
        if(autowiredValue != null) {
            if(!(autowiredValue instanceof ObjectFactory) && !dependencyType.isInstance(autowiredValue)) {
                throw new IllegalArgumentException("Value [" + autowiredValue + "] does not implement specified dependency type [" + dependencyType.getName() + "]");
            }

            this.resolvableDependencies.put(dependencyType, autowiredValue);
        }

    }

    public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException {
        return this.isAutowireCandidate(beanName, descriptor, this.getAutowireCandidateResolver());
    }

    protected boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) throws NoSuchBeanDefinitionException {
        String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
        if(this.containsBeanDefinition(beanDefinitionName)) {
            return this.isAutowireCandidate(beanName, this.getMergedLocalBeanDefinition(beanDefinitionName), descriptor, resolver);
        } else if(this.containsSingleton(beanName)) {
            return this.isAutowireCandidate(beanName, new RootBeanDefinition(this.getType(beanName)), descriptor, resolver);
        } else {
            BeanFactory parent = this.getParentBeanFactory();
            return parent instanceof DefaultListableBeanFactory?((DefaultListableBeanFactory)parent).isAutowireCandidate(beanName, descriptor, resolver):(parent instanceof ConfigurableListableBeanFactory?((ConfigurableListableBeanFactory)parent).isAutowireCandidate(beanName, descriptor):true);
        }
    }

    protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd, DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {
        String beanDefinitionName = BeanFactoryUtils.transformedBeanName(beanName);
        this.resolveBeanClass(mbd, beanDefinitionName, new Class[0]);
        if(mbd.isFactoryMethodUnique) {
            Object var7 = mbd.constructorArgumentLock;
            boolean resolve;
            synchronized(mbd.constructorArgumentLock) {
                resolve = mbd.resolvedConstructorOrFactoryMethod == null;
            }

            if(resolve) {
                (new ConstructorResolver(this)).resolveFactoryMethodIfPossible(mbd);
            }
        }

        return resolver.isAutowireCandidate(new BeanDefinitionHolder(mbd, beanName, this.getAliases(beanDefinitionName)), descriptor);
    }

    public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        BeanDefinition bd = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if(bd == null) {
            if(this.logger.isTraceEnabled()) {
                this.logger.trace("No bean named \'" + beanName + "\' found in " + this);
            }

            throw new NoSuchBeanDefinitionException(beanName);
        } else {
            return bd;
        }
    }

    public Iterator<String> getBeanNamesIterator() {
        CompositeIterator iterator = new CompositeIterator();
        iterator.add(this.beanDefinitionNames.iterator());
        iterator.add(this.manualSingletonNames.iterator());
        return iterator;
    }

    public void clearMetadataCache() {
        super.clearMetadataCache();
        this.clearByTypeCache();
    }

    public void freezeConfiguration() {
        this.configurationFrozen = true;
        this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);
    }

    public boolean isConfigurationFrozen() {
        return this.configurationFrozen;
    }

    protected boolean isBeanEligibleForMetadataCaching(String beanName) {
        return this.configurationFrozen || super.isBeanEligibleForMetadataCaching(beanName);
    }

    public void preInstantiateSingletons() throws BeansException {
        if(this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }

        ArrayList beanNames = new ArrayList(this.beanDefinitionNames);
        Iterator var2 = beanNames.iterator();

        while(true) {
            while(true) {
                String beanName;
                RootBeanDefinition singletonInstance;
                do {
                    do {
                        do {
                            if(!var2.hasNext()) {
                                var2 = beanNames.iterator();

                                while(var2.hasNext()) {
                                    beanName = (String)var2.next();
                                    Object singletonInstance1 = this.getSingleton(beanName);
                                    if(singletonInstance1 instanceof SmartInitializingSingleton) {
                                        final SmartInitializingSingleton smartSingleton1 = (SmartInitializingSingleton)singletonInstance1;
                                        if(System.getSecurityManager() != null) {
                                            AccessController.doPrivileged(new PrivilegedAction() {
                                                public Object run() {
                                                    smartSingleton1.afterSingletonsInstantiated();
                                                    return null;
                                                }
                                            }, this.getAccessControlContext());
                                        } else {
                                            smartSingleton1.afterSingletonsInstantiated();
                                        }
                                    }
                                }

                                return;
                            }

                            beanName = (String)var2.next();
                            singletonInstance = this.getMergedLocalBeanDefinition(beanName);
                        } while(singletonInstance.isAbstract());
                    } while(!singletonInstance.isSingleton());
                } while(singletonInstance.isLazyInit());

                if(this.isFactoryBean(beanName)) {
                    final FactoryBean smartSingleton = (FactoryBean)this.getBean("&" + beanName);
                    boolean isEagerInit;
                    if(System.getSecurityManager() != null && smartSingleton instanceof SmartFactoryBean) {
                        isEagerInit = ((Boolean)AccessController.doPrivileged(new PrivilegedAction() {
                            public Boolean run() {
                                return Boolean.valueOf(((SmartFactoryBean)smartSingleton).isEagerInit());
                            }
                        }, this.getAccessControlContext())).booleanValue();
                    } else {
                        isEagerInit = smartSingleton instanceof SmartFactoryBean && ((SmartFactoryBean)smartSingleton).isEagerInit();
                    }

                    if(isEagerInit) {
                        this.getBean(beanName);
                    }
                } else {
                    this.getBean(beanName);
                }
            }
        }
    }

    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
        Assert.hasText(beanName, "Bean name must not be empty");
        Assert.notNull(beanDefinition, "BeanDefinition must not be null");
        if(beanDefinition instanceof AbstractBeanDefinition) {
            try {
                ((AbstractBeanDefinition)beanDefinition).validate();
            } catch (BeanDefinitionValidationException var9) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9);
            }
        }

        BeanDefinition oldBeanDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if(oldBeanDefinition != null) {
            if(!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean \'" + beanName + "\': There is already [" + oldBeanDefinition + "] bound.");
            }

            if(oldBeanDefinition.getRole() < beanDefinition.getRole()) {
                if(this.logger.isWarnEnabled()) {
                    this.logger.warn("Overriding user-defined bean definition for bean \'" + beanName + "\' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            } else if(!beanDefinition.equals(oldBeanDefinition)) {
                if(this.logger.isInfoEnabled()) {
                    this.logger.info("Overriding bean definition for bean \'" + beanName + "\' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
                }
            } else if(this.logger.isDebugEnabled()) {
                this.logger.debug("Overriding bean definition for bean \'" + beanName + "\' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]");
            }

            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if(this.hasBeanCreationStarted()) {
                Map var4 = this.beanDefinitionMap;
                synchronized(this.beanDefinitionMap) {
                    this.beanDefinitionMap.put(beanName, beanDefinition);
                    ArrayList updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1);
                    updatedDefinitions.addAll(this.beanDefinitionNames);
                    updatedDefinitions.add(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                    if(this.manualSingletonNames.contains(beanName)) {
                        LinkedHashSet updatedSingletons = new LinkedHashSet(this.manualSingletonNames);
                        updatedSingletons.remove(beanName);
                        this.manualSingletonNames = updatedSingletons;
                    }
                }
            } else {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.manualSingletonNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
        }

        if(oldBeanDefinition != null || this.containsSingleton(beanName)) {
            this.resetBeanDefinition(beanName);
        }

    }

    public void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
        Assert.hasText(beanName, "\'beanName\' must not be empty");
        BeanDefinition bd = (BeanDefinition)this.beanDefinitionMap.remove(beanName);
        if(bd == null) {
            if(this.logger.isTraceEnabled()) {
                this.logger.trace("No bean named \'" + beanName + "\' found in " + this);
            }

            throw new NoSuchBeanDefinitionException(beanName);
        } else {
            if(this.hasBeanCreationStarted()) {
                Map var3 = this.beanDefinitionMap;
                synchronized(this.beanDefinitionMap) {
                    ArrayList updatedDefinitions = new ArrayList(this.beanDefinitionNames);
                    updatedDefinitions.remove(beanName);
                    this.beanDefinitionNames = updatedDefinitions;
                }
            } else {
                this.beanDefinitionNames.remove(beanName);
            }

            this.frozenBeanDefinitionNames = null;
            this.resetBeanDefinition(beanName);
        }
    }

    protected void resetBeanDefinition(String beanName) {
        this.clearMergedBeanDefinition(beanName);
        this.destroySingleton(beanName);
        Iterator var2 = this.beanDefinitionNames.iterator();

        while(var2.hasNext()) {
            String bdName = (String)var2.next();
            if(!beanName.equals(bdName)) {
                BeanDefinition bd = (BeanDefinition)this.beanDefinitionMap.get(bdName);
                if(beanName.equals(bd.getParentName())) {
                    this.resetBeanDefinition(bdName);
                }
            }
        }

    }

    protected boolean allowAliasOverriding() {
        return this.isAllowBeanDefinitionOverriding();
    }

    public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
        super.registerSingleton(beanName, singletonObject);
        if(this.hasBeanCreationStarted()) {
            Map var3 = this.beanDefinitionMap;
            synchronized(this.beanDefinitionMap) {
                if(!this.beanDefinitionMap.containsKey(beanName)) {
                    LinkedHashSet updatedSingletons = new LinkedHashSet(this.manualSingletonNames.size() + 1);
                    updatedSingletons.addAll(this.manualSingletonNames);
                    updatedSingletons.add(beanName);
                    this.manualSingletonNames = updatedSingletons;
                }
            }
        } else if(!this.beanDefinitionMap.containsKey(beanName)) {
            this.manualSingletonNames.add(beanName);
        }

        this.clearByTypeCache();
    }

    public void destroySingleton(String beanName) {
        super.destroySingleton(beanName);
        this.manualSingletonNames.remove(beanName);
        this.clearByTypeCache();
    }

    public void destroySingletons() {
        super.destroySingletons();
        this.manualSingletonNames.clear();
        this.clearByTypeCache();
    }

    private void clearByTypeCache() {
        this.allBeanNamesByType.clear();
        this.singletonBeanNamesByType.clear();
    }

    public <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException {
        NamedBeanHolder namedBean = this.resolveNamedBean(requiredType, (Object[])null);
        if(namedBean != null) {
            return namedBean;
        } else {
            BeanFactory parent = this.getParentBeanFactory();
            if(parent instanceof AutowireCapableBeanFactory) {
                return ((AutowireCapableBeanFactory)parent).resolveNamedBean(requiredType);
            } else {
                throw new NoSuchBeanDefinitionException(requiredType);
            }
        }
    }

    private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
        Assert.notNull(requiredType, "Required type must not be null");
        String[] candidateNames = this.getBeanNamesForType(requiredType);
        String[] candidateName;
        int beanInstance;
        int var7;
        String beanName;
        if(candidateNames.length > 1) {
            ArrayList candidates = new ArrayList(candidateNames.length);
            candidateName = candidateNames;
            beanInstance = candidateNames.length;

            for(var7 = 0; var7 < beanInstance; ++var7) {
                beanName = candidateName[var7];
                if(!this.containsBeanDefinition(beanName) || this.getBeanDefinition(beanName).isAutowireCandidate()) {
                    candidates.add(beanName);
                }
            }

            if(!candidates.isEmpty()) {
                candidateNames = (String[])candidates.toArray(new String[candidates.size()]);
            }
        }

        if(candidateNames.length == 1) {
            String var10 = candidateNames[0];
            return new NamedBeanHolder(var10, this.getBean(var10, requiredType, args));
        } else if(candidateNames.length > 1) {
            LinkedHashMap var9 = new LinkedHashMap(candidateNames.length);
            candidateName = candidateNames;
            beanInstance = candidateNames.length;

            for(var7 = 0; var7 < beanInstance; ++var7) {
                beanName = candidateName[var7];
                if(this.containsSingleton(beanName)) {
                    var9.put(beanName, this.getBean(beanName, requiredType, args));
                } else {
                    var9.put(beanName, this.getType(beanName));
                }
            }

            String var11 = this.determinePrimaryCandidate(var9, requiredType);
            if(var11 == null) {
                var11 = this.determineHighestPriorityCandidate(var9, requiredType);
            }

            if(var11 != null) {
                Object var12 = var9.get(var11);
                if(var12 instanceof Class) {
                    var12 = this.getBean(var11, requiredType, args);
                }

                return new NamedBeanHolder(var11, var12);
            } else {
                throw new NoUniqueBeanDefinitionException(requiredType, var9.keySet());
            }
        } else {
            return null;
        }
    }

    public Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
        descriptor.initParameterNameDiscovery(this.getParameterNameDiscoverer());
        if(javaUtilOptionalClass == descriptor.getDependencyType()) {
            return (new DefaultListableBeanFactory.OptionalDependencyFactory(null)).createOptionalDependency(descriptor, requestingBeanName, new Object[0]);
        } else if(ObjectFactory.class != descriptor.getDependencyType() && ObjectProvider.class != descriptor.getDependencyType()) {
            if(javaxInjectProviderClass == descriptor.getDependencyType()) {
                return (new DefaultListableBeanFactory.Jsr330ProviderFactory(null)).createDependencyProvider(descriptor, requestingBeanName);
            } else {
                Object result = this.getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, requestingBeanName);
                if(result == null) {
                    result = this.doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
                }

                return result;
            }
        } else {
            return new DefaultListableBeanFactory.DependencyObjectProvider(descriptor, requestingBeanName);
        }
    }

    public Object doResolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
        InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);

        Object entry;
        try {
            Object shortcut = descriptor.resolveShortcut(this);
            if(shortcut != null) {
                Object type1 = shortcut;
                return type1;
            }

            Class type = descriptor.getDependencyType();
            Object value = this.getAutowireCandidateResolver().getSuggestedValue(descriptor);
            Object matchingBeans1;
            if(value != null) {
                if(value instanceof String) {
                    String multipleBeans1 = this.resolveEmbeddedValue((String)value);
                    BeanDefinition matchingBeans2 = beanName != null && this.containsBean(beanName)?this.getMergedBeanDefinition(beanName):null;
                    value = this.evaluateBeanDefinitionString(multipleBeans1, matchingBeans2);
                }

                TypeConverter multipleBeans2 = typeConverter != null?typeConverter:this.getTypeConverter();
                matchingBeans1 = descriptor.getField() != null?multipleBeans2.convertIfNecessary(value, type, descriptor.getField()):multipleBeans2.convertIfNecessary(value, type, descriptor.getMethodParameter());
                return matchingBeans1;
            }

            Object multipleBeans = this.resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if(multipleBeans != null) {
                matchingBeans1 = multipleBeans;
                return matchingBeans1;
            }

            Map matchingBeans = this.findAutowireCandidates(beanName, type, descriptor);
            String autowiredBeanName;
            if(matchingBeans.isEmpty()) {
                if(this.isRequired(descriptor)) {
                    this.raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }

                autowiredBeanName = null;
                return autowiredBeanName;
            }

            Object instanceCandidate;
            if(matchingBeans.size() > 1) {
                autowiredBeanName = this.determineAutowireCandidate(matchingBeans, descriptor);
                if(autowiredBeanName == null) {
                    if(!this.isRequired(descriptor) && this.indicatesMultipleBeans(type)) {
                        entry = null;
                        return entry;
                    }

                    entry = descriptor.resolveNotUnique(type, matchingBeans);
                    return entry;
                }

                instanceCandidate = matchingBeans.get(autowiredBeanName);
            } else {
                Entry entry1 = (Entry)matchingBeans.entrySet().iterator().next();
                autowiredBeanName = (String)entry1.getKey();
                instanceCandidate = entry1.getValue();
            }

            if(autowiredBeanNames != null) {
                autowiredBeanNames.add(autowiredBeanName);
            }

            entry = instanceCandidate instanceof Class?descriptor.resolveCandidate(autowiredBeanName, type, this):instanceCandidate;
        } finally {
            ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
        }

        return entry;
    }

    private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) {
        Class type = descriptor.getDependencyType();
        Class valueType;
        Map matchingBeans;
        Class mapType1;
        if(type.isArray()) {
            mapType1 = type.getComponentType();
            ResolvableType keyType2 = descriptor.getResolvableType();
            valueType = keyType2.resolve();
            if(valueType != null && valueType != type) {
                type = valueType;
                mapType1 = keyType2.getComponentType().resolve();
            }

            if(mapType1 == null) {
                return null;
            } else {
                matchingBeans = this.findAutowireCandidates(beanName, mapType1, new DefaultListableBeanFactory.MultiElementDescriptor(descriptor));
                if(matchingBeans.isEmpty()) {
                    return null;
                } else {
                    if(autowiredBeanNames != null) {
                        autowiredBeanNames.addAll(matchingBeans.keySet());
                    }

                    TypeConverter converter = typeConverter != null?typeConverter:this.getTypeConverter();
                    Object result = converter.convertIfNecessary(matchingBeans.values(), type);
                    if(this.getDependencyComparator() != null && result instanceof Object[]) {
                        Arrays.sort((Object[])((Object[])result), this.adaptDependencyComparator(matchingBeans));
                    }

                    return result;
                }
            }
        } else if(Collection.class.isAssignableFrom(type) && type.isInterface()) {
            mapType1 = descriptor.getResolvableType().asCollection().resolveGeneric(new int[0]);
            if(mapType1 == null) {
                return null;
            } else {
                Map keyType1 = this.findAutowireCandidates(beanName, mapType1, new DefaultListableBeanFactory.MultiElementDescriptor(descriptor));
                if(keyType1.isEmpty()) {
                    return null;
                } else {
                    if(autowiredBeanNames != null) {
                        autowiredBeanNames.addAll(keyType1.keySet());
                    }

                    TypeConverter valueType1 = typeConverter != null?typeConverter:this.getTypeConverter();
                    Object matchingBeans1 = valueType1.convertIfNecessary(keyType1.values(), type);
                    if(this.getDependencyComparator() != null && matchingBeans1 instanceof List) {
                        Collections.sort((List)matchingBeans1, this.adaptDependencyComparator(keyType1));
                    }

                    return matchingBeans1;
                }
            }
        } else if(Map.class == type) {
            ResolvableType mapType = descriptor.getResolvableType().asMap();
            Class keyType = mapType.resolveGeneric(new int[]{0});
            if(String.class != keyType) {
                return null;
            } else {
                valueType = mapType.resolveGeneric(new int[]{1});
                if(valueType == null) {
                    return null;
                } else {
                    matchingBeans = this.findAutowireCandidates(beanName, valueType, new DefaultListableBeanFactory.MultiElementDescriptor(descriptor));
                    if(matchingBeans.isEmpty()) {
                        return null;
                    } else {
                        if(autowiredBeanNames != null) {
                            autowiredBeanNames.addAll(matchingBeans.keySet());
                        }

                        return matchingBeans;
                    }
                }
            }
        } else {
            return null;
        }
    }

    private boolean isRequired(DependencyDescriptor descriptor) {
        AutowireCandidateResolver resolver = this.getAutowireCandidateResolver();
        return resolver instanceof SimpleAutowireCandidateResolver?((SimpleAutowireCandidateResolver)resolver).isRequired(descriptor):descriptor.isRequired();
    }

    private boolean indicatesMultipleBeans(Class<?> type) {
        return type.isArray() || type.isInterface() && (Collection.class.isAssignableFrom(type) || Map.class.isAssignableFrom(type));
    }

    private Comparator<Object> adaptDependencyComparator(Map<String, Object> matchingBeans) {
        Comparator comparator = this.getDependencyComparator();
        return comparator instanceof OrderComparator?((OrderComparator)comparator).withSourceProvider(this.createFactoryAwareOrderSourceProvider(matchingBeans)):comparator;
    }

    private DefaultListableBeanFactory.FactoryAwareOrderSourceProvider createFactoryAwareOrderSourceProvider(Map<String, Object> beans) {
        IdentityHashMap instancesToBeanNames = new IdentityHashMap();
        Iterator var3 = beans.entrySet().iterator();

        while(var3.hasNext()) {
            Entry entry = (Entry)var3.next();
            instancesToBeanNames.put(entry.getValue(), entry.getKey());
        }

        return new DefaultListableBeanFactory.FactoryAwareOrderSourceProvider(instancesToBeanNames);
    }

    protected Map<String, Object> findAutowireCandidates(String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
        String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.isEager());
        LinkedHashMap result = new LinkedHashMap(candidateNames.length);
        Iterator fallbackDescriptor = this.resolvableDependencies.keySet().iterator();

        while(fallbackDescriptor.hasNext()) {
            Class autowiringType = (Class)fallbackDescriptor.next();
            if(autowiringType.isAssignableFrom(requiredType)) {
                Object autowiringValue = this.resolvableDependencies.get(autowiringType);
                autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
                if(requiredType.isInstance(autowiringValue)) {
                    result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                    break;
                }
            }
        }

        String[] var11 = candidateNames;
        int var13 = candidateNames.length;

        int var15;
        for(var15 = 0; var15 < var13; ++var15) {
            String candidate = var11[var15];
            if(!this.isSelfReference(beanName, candidate) && this.isAutowireCandidate(candidate, descriptor)) {
                this.addCandidateEntry(result, candidate, descriptor, requiredType);
            }
        }

        if(result.isEmpty() && !this.indicatesMultipleBeans(requiredType)) {
            DependencyDescriptor var12 = descriptor.forFallbackMatch();
            String[] var14 = candidateNames;
            var15 = candidateNames.length;

            String candidate1;
            int var16;
            for(var16 = 0; var16 < var15; ++var16) {
                candidate1 = var14[var16];
                if(!this.isSelfReference(beanName, candidate1) && this.isAutowireCandidate(candidate1, var12)) {
                    this.addCandidateEntry(result, candidate1, descriptor, requiredType);
                }
            }

            if(result.isEmpty()) {
                var14 = candidateNames;
                var15 = candidateNames.length;

                for(var16 = 0; var16 < var15; ++var16) {
                    candidate1 = var14[var16];
                    if(this.isSelfReference(beanName, candidate1) && (!(descriptor instanceof DefaultListableBeanFactory.MultiElementDescriptor) || !beanName.equals(candidate1)) && this.isAutowireCandidate(candidate1, var12)) {
                        this.addCandidateEntry(result, candidate1, descriptor, requiredType);
                    }
                }
            }
        }

        return result;
    }

    private void addCandidateEntry(Map<String, Object> candidates, String candidateName, DependencyDescriptor descriptor, Class<?> requiredType) {
        if(!(descriptor instanceof DefaultListableBeanFactory.MultiElementDescriptor) && !this.containsSingleton(candidateName)) {
            candidates.put(candidateName, this.getType(candidateName));
        } else {
            candidates.put(candidateName, descriptor.resolveCandidate(candidateName, requiredType, this));
        }

    }

    protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
        Class requiredType = descriptor.getDependencyType();
        String primaryCandidate = this.determinePrimaryCandidate(candidates, requiredType);
        if(primaryCandidate != null) {
            return primaryCandidate;
        } else {
            String priorityCandidate = this.determineHighestPriorityCandidate(candidates, requiredType);
            if(priorityCandidate != null) {
                return priorityCandidate;
            } else {
                Iterator var6 = candidates.entrySet().iterator();

                String candidateName;
                Object beanInstance;
                do {
                    if(!var6.hasNext()) {
                        return null;
                    }

                    Entry entry = (Entry)var6.next();
                    candidateName = (String)entry.getKey();
                    beanInstance = entry.getValue();
                } while((beanInstance == null || !this.resolvableDependencies.containsValue(beanInstance)) && !this.matchesBeanName(candidateName, descriptor.getDependencyName()));

                return candidateName;
            }
        }
    }

    protected String determinePrimaryCandidate(Map<String, Object> candidates, Class<?> requiredType) {
        String primaryBeanName = null;
        Iterator var4 = candidates.entrySet().iterator();

        while(var4.hasNext()) {
            Entry entry = (Entry)var4.next();
            String candidateBeanName = (String)entry.getKey();
            Object beanInstance = entry.getValue();
            if(this.isPrimary(candidateBeanName, beanInstance)) {
                if(primaryBeanName != null) {
                    boolean candidateLocal = this.containsBeanDefinition(candidateBeanName);
                    boolean primaryLocal = this.containsBeanDefinition(primaryBeanName);
                    if(candidateLocal && primaryLocal) {
                        throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "more than one \'primary\' bean found among candidates: " + candidates.keySet());
                    }

                    if(candidateLocal) {
                        primaryBeanName = candidateBeanName;
                    }
                } else {
                    primaryBeanName = candidateBeanName;
                }
            }
        }

        return primaryBeanName;
    }

    protected String determineHighestPriorityCandidate(Map<String, Object> candidates, Class<?> requiredType) {
        String highestPriorityBeanName = null;
        Integer highestPriority = null;
        Iterator var5 = candidates.entrySet().iterator();

        while(var5.hasNext()) {
            Entry entry = (Entry)var5.next();
            String candidateBeanName = (String)entry.getKey();
            Object beanInstance = entry.getValue();
            Integer candidatePriority = this.getPriority(beanInstance);
            if(candidatePriority != null) {
                if(highestPriorityBeanName != null) {
                    if(candidatePriority.equals(highestPriority)) {
                        throw new NoUniqueBeanDefinitionException(requiredType, candidates.size(), "Multiple beans found with the same priority (\'" + highestPriority + "\') among candidates: " + candidates.keySet());
                    }

                    if(candidatePriority.intValue() < highestPriority.intValue()) {
                        highestPriorityBeanName = candidateBeanName;
                        highestPriority = candidatePriority;
                    }
                } else {
                    highestPriorityBeanName = candidateBeanName;
                    highestPriority = candidatePriority;
                }
            }
        }

        return highestPriorityBeanName;
    }

    protected boolean isPrimary(String beanName, Object beanInstance) {
        if(this.containsBeanDefinition(beanName)) {
            return this.getMergedLocalBeanDefinition(beanName).isPrimary();
        } else {
            BeanFactory parent = this.getParentBeanFactory();
            return parent instanceof DefaultListableBeanFactory && ((DefaultListableBeanFactory)parent).isPrimary(beanName, beanInstance);
        }
    }

    protected Integer getPriority(Object beanInstance) {
        Comparator comparator = this.getDependencyComparator();
        return comparator instanceof OrderComparator?((OrderComparator)comparator).getPriority(beanInstance):null;
    }

    protected boolean matchesBeanName(String beanName, String candidateName) {
        return candidateName != null && (candidateName.equals(beanName) || ObjectUtils.containsElement(this.getAliases(beanName), candidateName));
    }

    private boolean isSelfReference(String beanName, String candidateName) {
        return beanName != null && candidateName != null && (beanName.equals(candidateName) || this.containsBeanDefinition(candidateName) && beanName.equals(this.getMergedLocalBeanDefinition(candidateName).getFactoryBeanName()));
    }

    private void raiseNoMatchingBeanFound(Class<?> type, ResolvableType resolvableType, DependencyDescriptor descriptor) throws BeansException {
        this.checkBeanNotOfRequiredType(type, descriptor);
        throw new NoSuchBeanDefinitionException(resolvableType, "expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: " + ObjectUtils.nullSafeToString(descriptor.getAnnotations()));
    }

    private void checkBeanNotOfRequiredType(Class<?> type, DependencyDescriptor descriptor) {
        Iterator parent = this.beanDefinitionNames.iterator();

        while(parent.hasNext()) {
            String beanName = (String)parent.next();
            RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
            Class targetType = mbd.getTargetType();
            if(targetType != null && type.isAssignableFrom(targetType) && this.isAutowireCandidate(beanName, mbd, descriptor, this.getAutowireCandidateResolver())) {
                Object beanInstance = this.getSingleton(beanName, false);
                Class beanType = beanInstance != null?beanInstance.getClass():this.predictBeanType(beanName, mbd, new Class[0]);
                if(!type.isAssignableFrom(beanType)) {
                    throw new BeanNotOfRequiredTypeException(beanName, type, beanType);
                }
            }
        }

        BeanFactory parent1 = this.getParentBeanFactory();
        if(parent1 instanceof DefaultListableBeanFactory) {
            ((DefaultListableBeanFactory)parent1).checkBeanNotOfRequiredType(type, descriptor);
        }

    }

    public String toString() {
        StringBuilder sb = new StringBuilder(ObjectUtils.identityToString(this));
        sb.append(": defining beans [");
        sb.append(StringUtils.collectionToCommaDelimitedString(this.beanDefinitionNames));
        sb.append("]; ");
        BeanFactory parent = this.getParentBeanFactory();
        if(parent == null) {
            sb.append("root of factory hierarchy");
        } else {
            sb.append("parent: ").append(ObjectUtils.identityToString(parent));
        }

        return sb.toString();
    }

    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
        throw new NotSerializableException("DefaultListableBeanFactory itself is not deserializable - just a SerializedBeanFactoryReference is");
    }

    protected Object writeReplace() throws ObjectStreamException {
        if(this.serializationId != null) {
            return new DefaultListableBeanFactory.SerializedBeanFactoryReference(this.serializationId);
        } else {
            throw new NotSerializableException("DefaultListableBeanFactory has no serialization id");
        }
    }

    static {
        try {
            javaUtilOptionalClass = ClassUtils.forName("java.util.Optional", DefaultListableBeanFactory.class.getClassLoader());
        } catch (ClassNotFoundException var2) {
            ;
        }

        try {
            javaxInjectProviderClass = ClassUtils.forName("javax.inject.Provider", DefaultListableBeanFactory.class.getClassLoader());
        } catch (ClassNotFoundException var1) {
            ;
        }

        serializableFactories = new ConcurrentHashMap(8);
    }

    private static class MultiElementDescriptor extends DefaultListableBeanFactory.NestedDependencyDescriptor {
        public MultiElementDescriptor(DependencyDescriptor original) {
            super(original);
        }
    }

    private static class NestedDependencyDescriptor extends DependencyDescriptor {
        public NestedDependencyDescriptor(DependencyDescriptor original) {
            super(original);
            this.increaseNestingLevel();
        }
    }

    private class FactoryAwareOrderSourceProvider implements OrderSourceProvider {
        private final Map<Object, String> instancesToBeanNames;

        public FactoryAwareOrderSourceProvider(Map<Object, String> var1) {
            this.instancesToBeanNames = instancesToBeanNames;
        }

        public Object getOrderSource(Object obj) {
            RootBeanDefinition beanDefinition = this.getRootBeanDefinition((String)this.instancesToBeanNames.get(obj));
            if(beanDefinition == null) {
                return null;
            } else {
                ArrayList sources = new ArrayList(2);
                Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
                if(factoryMethod != null) {
                    sources.add(factoryMethod);
                }

                Class targetType = beanDefinition.getTargetType();
                if(targetType != null && targetType != obj.getClass()) {
                    sources.add(targetType);
                }

                return sources.toArray(new Object[sources.size()]);
            }
        }

        private RootBeanDefinition getRootBeanDefinition(String beanName) {
            if(beanName != null && DefaultListableBeanFactory.this.containsBeanDefinition(beanName)) {
                BeanDefinition bd = DefaultListableBeanFactory.this.getMergedBeanDefinition(beanName);
                if(bd instanceof RootBeanDefinition) {
                    return (RootBeanDefinition)bd;
                }
            }

            return null;
        }
    }

    private class Jsr330ProviderFactory {
        private Jsr330ProviderFactory() {
        }

        public Object createDependencyProvider(DependencyDescriptor descriptor, String beanName) {
            return DefaultListableBeanFactory.this.new Jsr330DependencyProvider(descriptor, beanName);
        }
    }

    private class Jsr330DependencyProvider extends DefaultListableBeanFactory.DependencyObjectProvider implements Provider<Object> {
        public Jsr330DependencyProvider(DependencyDescriptor descriptor, String beanName) {
            super(descriptor, beanName);
        }

        public Object get() throws BeansException {
            return this.getObject();
        }
    }

    private class DependencyObjectProvider implements ObjectProvider<Object>, Serializable {
        private final DependencyDescriptor descriptor;
        private final boolean optional;
        private final String beanName;

        public DependencyObjectProvider(DependencyDescriptor descriptor, String beanName) {
            this.descriptor = new DefaultListableBeanFactory.NestedDependencyDescriptor(descriptor);
            this.optional = this.descriptor.getDependencyType() == DefaultListableBeanFactory.javaUtilOptionalClass;
            this.beanName = beanName;
        }

        public Object getObject() throws BeansException {
            return this.optional?(DefaultListableBeanFactory.this.new OptionalDependencyFactory(null)).createOptionalDependency(this.descriptor, this.beanName, new Object[0]):DefaultListableBeanFactory.this.doResolveDependency(this.descriptor, this.beanName, (Set)null, (TypeConverter)null);
        }

        public Object getObject(final Object... args) throws BeansException {
            if(this.optional) {
                return (DefaultListableBeanFactory.this.new OptionalDependencyFactory(null)).createOptionalDependency(this.descriptor, this.beanName, args);
            } else {
                DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
                    public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
                        return ((AbstractBeanFactory)beanFactory).getBean(beanName, requiredType, args);
                    }
                };
                return DefaultListableBeanFactory.this.doResolveDependency(descriptorToUse, this.beanName, (Set)null, (TypeConverter)null);
            }
        }

        public Object getIfAvailable() throws BeansException {
            if(this.optional) {
                return (DefaultListableBeanFactory.this.new OptionalDependencyFactory(null)).createOptionalDependency(this.descriptor, this.beanName, new Object[0]);
            } else {
                DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
                    public boolean isRequired() {
                        return false;
                    }
                };
                return DefaultListableBeanFactory.this.doResolveDependency(descriptorToUse, this.beanName, (Set)null, (TypeConverter)null);
            }
        }

        public Object getIfUnique() throws BeansException {
            DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
                public boolean isRequired() {
                    return false;
                }

                public Object resolveNotUnique(Class<?> type, Map<String, Object> matchingBeans) {
                    return null;
                }
            };
            return this.optional?(DefaultListableBeanFactory.this.new OptionalDependencyFactory(null)).createOptionalDependency(descriptorToUse, this.beanName, new Object[0]):DefaultListableBeanFactory.this.doResolveDependency(descriptorToUse, this.beanName, (Set)null, (TypeConverter)null);
        }
    }

    @UsesJava8
    private class OptionalDependencyFactory {
        private OptionalDependencyFactory() {
        }

        public Object createOptionalDependency(final DependencyDescriptor descriptor, String beanName, final Object... args) {
            DefaultListableBeanFactory.NestedDependencyDescriptor descriptorToUse = new DefaultListableBeanFactory.NestedDependencyDescriptor(descriptor) {
                public boolean isRequired() {
                    return false;
                }

                public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory) {
                    return !ObjectUtils.isEmpty(args)?beanFactory.getBean(beanName, new Object[]{requiredType, args}):super.resolveCandidate(beanName, requiredType, beanFactory);
                }
            };
            return Optional.ofNullable(DefaultListableBeanFactory.this.doResolveDependency(descriptorToUse, beanName, (Set)null, (TypeConverter)null));
        }
    }

    private static class SerializedBeanFactoryReference implements Serializable {
        private final String id;

        public SerializedBeanFactoryReference(String id) {
            this.id = id;
        }

        private Object readResolve() {
            Reference ref = (Reference)DefaultListableBeanFactory.serializableFactories.get(this.id);
            if(ref != null) {
                Object result = ref.get();
                if(result != null) {
                    return result;
                }
            }

            return new StaticListableBeanFactory(Collections.emptyMap());
        }
    }
}

1六、XmlBeanFactory 基於xml的工廠bean

@Deprecated
public class XmlBeanFactory extends DefaultListableBeanFactory {
    private final XmlBeanDefinitionReader reader;

    public XmlBeanFactory(Resource resource) throws BeansException {
        this(resource, (BeanFactory)null);
    }

    public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
        super(parentBeanFactory);
        this.reader = new XmlBeanDefinitionReader(this);
        this.reader.loadBeanDefinitions(resource);
    }
}

到這裏爲此全部與beans相關的類圖具體實現都在這裏,可是咱們這裏只是瞭解有那些類參與了。可是具體某個類在實際spring-beans中起的具體做用咱們會在下面章節具體分析。

相關文章
相關標籤/搜索