主题
除了Spring 学习记录5 BeanFactory 里写的几个接口外,BeanFactory的实现类还实现了一些其他接口,这篇文章主要介绍这些接口和实现类.
结构
DefaultListableBeanFactory和它的父类们除了实现了BF的各种接口以外还实现了AliasRegistry和BeanDefinitionRegistry接口.而且不同等级的父类和BF的相关接口都有交集..
AliasRegistry
这个接口根据说明来看意思是提供别名注册的服务.虽然没有实际使用过别名,不过1个bean确实可以有N个别名.
/*
* Copyright 2002-2008 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.core; /**
* Common interface for managing aliases. Serves as super-interface for
* {@link org.springframework.beans.factory.support.BeanDefinitionRegistry}.
*
* @author Juergen Hoeller
* @since 2.5.2
*/
public interface AliasRegistry { /**
* Given a name, register an alias for it.
* @param name the canonical name
* @param alias the alias to be registered
* @throws IllegalStateException if the alias is already in use
* and may not be overridden
*/
void registerAlias(String name, String alias); /**
* Remove the specified alias from this registry.
* @param alias the alias to remove
* @throws IllegalStateException if no such alias was found
*/
void removeAlias(String alias); /**
* Determine whether this given name is defines as an alias
* (as opposed to the name of an actually registered component).
* @param beanName the bean name to check
* @return whether the given name is an alias
*/
boolean isAlias(String beanName); /**
* Return the aliases for the given name, if defined.
* @param name the name to check for aliases
* @return the aliases, or an empty array if none
*/
String[] getAliases(String name); }
接口就4个方法.
1.为1个beanname注册1个别名,
2.删除1个别名
3.判断1个name是否是别名
4.根据beanname获取所有别名.
SimpleAliasRegistry
这个类实现了AliasRegistry,用了1个ConcurrentHashMap来存储所有别名的映射关系.
测试代码:
package spring.bf; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.core.SimpleAliasRegistry;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.StringValueResolver; import java.util.Arrays; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:test-application-context.xml")
public class SimpleAliasRegistryTest { SimpleAliasRegistry simpleAliasRegistry = new SimpleAliasRegistry(); /**
* 别名不能循环引用
* 会调用checkForAliasCircle方法,做循环引用的检查
* 里面会调用canonicalName方法,这个方法会不停的用传入的name当做别名去找他对应的beanname,层层找下去,找到最后1个beanname以后和alias比较一下,如果一直,说明有循环引用就抛出异常
*/
@Test
public void test() {
simpleAliasRegistry.registerAlias("b1", "a1");
simpleAliasRegistry.registerAlias("a1", "a2");
//simpleAliasRegistry.registerAlias("a2", "b1"); //java.lang.IllegalStateException: Cannot register alias 'b1' for name 'a2': Circular reference - 'a2' is a direct or indirect alias for 'b1' already
} /**
* 默认情况下别名可以覆盖
* 根据子类会不会重写allowAliasOverriding来做决定,默认是true
*/
@Test
public void test2() {
simpleAliasRegistry.registerAlias("b1", "a1");
simpleAliasRegistry.registerAlias("b2", "a1");
System.out.println(Arrays.toString(simpleAliasRegistry.getAliases("b1"))); // []
System.out.println(Arrays.toString(simpleAliasRegistry.getAliases("b2"))); // [a1]
} /**
* 移除不存在的bean会抛异常
* 所以调用之前可以先用isAlias做判断
*/
@Test
public void test3() {
//simpleAliasRegistry.removeAlias("not exists"); // java.lang.IllegalStateException: No alias 'not exists' registered
} // getAliases会调用retrieveAliases方法,它会递归调用自身,根据beanname找到alias,再把alias当做beanname,把所有的alias都找出来. /**
* 测试resolveAliases方法
*/
@Test
public void test4() {
simpleAliasRegistry.registerAlias("b1", "a1");
simpleAliasRegistry.registerAlias("b2", "a2");
// 报错
// java.lang.IllegalStateException: Cannot register resolved alias 'a1' (original: 'a2') for name 'b2': It is already registered for name 'b2'.
// 提示感觉有问题.其实应该提示It is already registered for name 'b1'.
// 因为alias a2 被解析为a1, 而a1已经指向的是beanname b1,所以不能再指向b2
simpleAliasRegistry.resolveAliases(new StringValueResolver() {
@Override
public String resolveStringValue(String strVal) {
if (strVal.equals("a2")) {
return "a1";
}
return strVal;
}
});
}
}
方法基本在测试里都测了.
另外感觉resolveAliases有一个提示有点问题,请参test4方法.
DefaultSingletonBeanRegistry
直接上注释吧...很多方法目前还不知道为什么这么写.什么时候会用到.看到后面的子类可能就会懂了.
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.beans.factory.support; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.SingletonBeanRegistry;
import org.springframework.core.SimpleAliasRegistry;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; /**
* Generic registry for shared bean instances, implementing the
* {@link org.springframework.beans.factory.config.SingletonBeanRegistry}.
* Allows for registering singleton instances that should be shared
* for all callers of the registry, to be obtained via bean name.
* <p>
* <p>Also supports registration of
* {@link org.springframework.beans.factory.DisposableBean} instances,
* (which might or might not correspond to registered singletons),
* to be destroyed on shutdown of the registry. Dependencies between
* beans can be registered to enforce an appropriate shutdown order.
* <p>
* <p>This class mainly serves as base class for
* {@link org.springframework.beans.factory.BeanFactory} implementations,
* factoring out the common management of singleton bean instances. Note that
* the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
* interface extends the {@link SingletonBeanRegistry} interface.
* <p>
* <p>Note that this class assumes neither a bean definition concept
* nor a specific creation process for bean instances, in contrast to
* {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory}
* (which inherit from it). Can alternatively also be used as a nested
* helper to delegate to.
*
* @author Juergen Hoeller
* @see #registerSingleton
* @see #registerDisposableBean
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
* @since 2.0
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { /**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
* concurrent Maps里不能put null,所以用这个代替
*/
protected static final Object NULL_OBJECT = new Object(); /**
* Logger available to subclasses
*/
protected final Log logger = LogFactory.getLog(getClass()); /**
* Cache of singleton objects: bean name --> bean instance
* 存单例的bean,FactoryBean也算
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64); /**
* Cache of singleton factories: bean name --> ObjectFactory
* 存ObjectFactory,我自己没用过.
* 测试的时候发现有循环引用的时候.比如A,B相互引用的时候,先扫描到A注册A.当前工厂的一个内部类对象会被注册到这里.有1个bean的引用指向B
*/
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16); /**
* Cache of early singleton objects: bean name --> bean instance
* 一般情况下可能这个map都是空的,只有2个bean相互引用的时候才会有值.
* 看英文解释似乎是一个bean还没被完全创建完的时候会被丢到这个map里.可能作用是先让其他bean先能够引用这个bean吧
* 测试A和B相互引用,先扫描到A的话A会放到这里里面,然后开始注册B,B注册完了再remove
*/
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16); /**
* Set of registered singletons, containing the bean names in registration order
* 注册的bean的name都会放到这里
*/
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64); /**
* Names of beans that are currently in creation
* 注册A的时候如果A和B相互引用,A会被放到这里里面.和earlySingletonObjects一起使用
*/
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16)); /**
* Names of beans currently excluded from in creation checks
* 创建bean过程中有一些bean已经在创建了在创建会报错,用这个可以排除掉这个检查,不知道啥时候会用到
*/
private final Set<String> inCreationCheckExclusions =
Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(16)); /**
* List of suppressed Exceptions, available for associating related causes
* 创建bean过程中出现一些特定的错误的时候可以无视这些错误继续创建
*/
private Set<Exception> suppressedExceptions; /**
* Flag that indicates whether we're currently within destroySingletons
* 是否正在销毁bean,可能是factory在destroy的时候就不能再创建bean了
*/
private boolean singletonsCurrentlyInDestruction = false; /**
* Disposable bean instances: bean name --> disposable instance
* 存disposableBean
*/
private final Map<String, Object> disposableBeans = new LinkedHashMap<String, Object>(); /**
* Map between containing bean names: bean name --> Set of bean names that the bean contains
* 似乎是用在innerbean和outerbean的时候使用.我一直没使用过这种bean
*/
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<String, Set<String>>(16); /**
* Map between dependent bean names: bean name --> Set of dependent bean names
* A中有B,那key就是B,value就是A.销毁B之前需要先销毁A
*/
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64); /**
* Map between depending bean names: bean name --> Set of bean names for the bean's dependencies
* 和dependentBeanMap刚好相反,A中有B和C的引用.那key是A value是B和C
*/
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64); /**
* 注册单例bean
*
* @param beanName
* @param singletonObject
* @throws IllegalStateException
*/
@Override
public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanName);
// 从singletonObjects获取bean,有bean说明已经注册过了不让重新注册
if (oldObject != null) {
throw new IllegalStateException("Could not register object [" + singletonObject +
"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
}
// 没注册过就掉注册方法
addSingleton(beanName, singletonObject);
}
} /**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* 注册1个单例bean
*
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 注册的单例bean放到singletonObjects和registeredSingletons里,null的话为了防止map抛出异常所以要put一个默认的obj
// 但是我也不知道为什么时候add的时候singletonFactories和earlySingletonObjects会有值,需要remove.
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
} /**
* Add the given singleton factory for building the specified singleton
* if necessary.
* <p>To be called for eager registration of singletons, e.g. to be able to
* resolve circular references.
* 和addSingleton几乎一样的道理
*
* @param beanName the name of the bean
* @param singletonFactory the factory for the singleton object
*/
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
} @Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
} /**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* 获取一个单例
*
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
// 从singletonObjects中先获取,如果非空就直接返回,如果是空的,判断是否正在创建中
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 如果正在创建就从earlySingletonObjects中获取A,B相互引用先加载A的时候A会被先放到earlySingletonObjects中而不是singletonObjects中,因为A还没创建就需要创建B
singletonObject = this.earlySingletonObjects.get(beanName);
// 目前我还没遇到过allowEarlyReference为true的情况
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = 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);
} /**
* Return the (raw) singleton object registered under the given name,
* creating and registering a new one if none registered yet.
* 也是获取bean,但是没有的时候可以从工厂里获取
*
* @param beanName the name of the bean
* @param singletonFactory the ObjectFactory to lazily create the singleton
* with, if necessary
* @return the registered singleton object
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
// 获取bean
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 如果工厂正在destroy.就直接抛异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName,
"Singleton bean creation not allowed while the singletons of this factory are in destruction " +
"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
if (logger.isDebugEnabled()) {
logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
// 创建之前做校验,如果已经正在创建了.就报错.
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
// 从工厂里获取
singletonObject = singletonFactory.getObject();
newSingleton = true;
} catch (IllegalStateException ex) {
// Has the singleton object implicitly appeared in the meantime ->
// if yes, proceed with it since the exception indicates that state.
// 之前有 同步 不知道什么时候会进这条分支
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
throw ex;
}
} catch (BeanCreationException ex) {
// 如果创建报错了.就把之前抑制的错误一起抛出,不过这个方法里没看到有添加抑制错误的.
if (recordSuppressedExceptions) {
for (Exception suppressedException : this.suppressedExceptions) {
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 把之前的singletonsCurrentlyInCreation添加的正在创建的bean删掉
afterSingletonCreation(beanName);
}
// 如果是新创建了bean就添加到相应的map里
if (newSingleton) {
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
} /**
* Register an Exception that happened to get suppressed during the creation of a
* singleton bean instance, e.g. a temporary circular reference resolution problem.
* 添加需要抑制的错误,创建过程中如果报了这些错误,不算出错.本类中没被调用
*
* @param ex the Exception to register
*/
protected void onSuppressedException(Exception ex) {
synchronized (this.singletonObjects) {
if (this.suppressedExceptions != null) {
this.suppressedExceptions.add(ex);
}
}
} /**
* Remove the bean with the given name from the singleton cache of this factory,
* to be able to clean up eager registration of a singleton if creation failed.
* 移除一个单例bean
*
* @param beanName the name of the bean
* @see #getSingletonMutex()
*/
protected void removeSingleton(String beanName) {
synchronized (this.singletonObjects) {
this.singletonObjects.remove(beanName);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.remove(beanName);
}
} @Override
public boolean containsSingleton(String beanName) {
return this.singletonObjects.containsKey(beanName);
} @Override
public String[] getSingletonNames() {
synchronized (this.singletonObjects) {
return StringUtils.toStringArray(this.registeredSingletons);
}
} @Override
public int getSingletonCount() {
synchronized (this.singletonObjects) {
return this.registeredSingletons.size();
}
} /**
* 设置一个bean正在被创建的标志,其实是放到一个跳过检查的set里.在这个set里的bean都会跳过检查.不然正在创建又执行创建需要抛出异常
* @param beanName
* @param inCreation
*/
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) && isActuallyInCreation(beanName));
} /**
* setCurrentlyInCreation方法只是用1个set集合记录需要跳过检查步骤的bean,singletonsCurrentlyInCreation里存的bean才是真正正在创建的bean
* @param beanName
* @return
*/
protected boolean isActuallyInCreation(String beanName) {
return isSingletonCurrentlyInCreation(beanName);
} /**
* Return whether the specified singleton bean is currently in creation
* (within the entire factory).
* 参考isActuallyInCreation方法
*
* @param beanName the name of the bean
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
} /**
* Callback before singleton creation.
* <p>The default implementation register the singleton as currently in creation.
* 在ObjectFactory创建bean之前检查一下是否已经正在创建这个bean了.
*
* @param beanName the name of the singleton about to be created
* @see #isSingletonCurrentlyInCreation
*/
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
} /**
* Callback after singleton creation.
* <p>The default implementation marks the singleton as not in creation anymore.
* 在ObjectFactory创建bean之后,需要这个bean正在创建的标志移除
*
* @param beanName the name of the singleton that has been created
* @see #isSingletonCurrentlyInCreation
*/
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton '" + beanName + "' isn't currently in creation");
}
} /**
* Add the given bean to the list of disposable beans in this registry.
* <p>Disposable beans usually correspond to registered singletons,
* matching the bean name but potentially being a different instance
* (for example, a DisposableBean adapter for a singleton that does not
* naturally implement Spring's DisposableBean interface).
* 注册DisposableBean
*
* @param beanName the name of the bean
* @param bean the bean instance
*/
public void registerDisposableBean(String beanName, DisposableBean bean) {
synchronized (this.disposableBeans) {
this.disposableBeans.put(beanName, bean);
}
} /**
* Register a containment relationship between two beans,
* e.g. between an inner bean and its containing outer bean.
* <p>Also registers the containing bean as dependent on the contained bean
* in terms of destruction order.
* 注册嵌套的bean.我从来没用过.
*
* @param containedBeanName the name of the contained (inner) bean 内部bean
* @param containingBeanName the name of the containing (outer) bean 外部bean
* @see #registerDependentBean
*/
public void registerContainedBean(String containedBeanName, String containingBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
Set<String> containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans != null && containedBeans.contains(containedBeanName)) {
return;
} // No entry yet -> fully synchronized manipulation of the containedBeans Set
synchronized (this.containedBeanMap) {
containedBeans = this.containedBeanMap.get(containingBeanName);
if (containedBeans == null) {
containedBeans = new LinkedHashSet<String>(8);
this.containedBeanMap.put(containingBeanName, containedBeans);
}
containedBeans.add(containedBeanName);
}
registerDependentBean(containedBeanName, containingBeanName);
} /**
* Register a dependent bean for the given bean,
* to be destroyed before the given bean is destroyed.
* 注册相互依赖的bean.比如A中有B.dependentBeanMap里key是B,value是A.需要先销毁A再销毁B
* dependenciesForBeanMap刚好相反.可以参考之前成员域上的注释
*
* @param beanName the name of the bean
* @param dependentBeanName the name of the dependent bean
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
// A quick check for an existing entry upfront, avoiding synchronization...
// 先把别名转化到真正的bean name
String canonicalName = canonicalName(beanName);
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans != null && dependentBeans.contains(dependentBeanName)) {
return;
} // No entry yet -> fully synchronized manipulation of the dependentBeans Set
// 依赖之前没注册过就注册到相应的map里去
synchronized (this.dependentBeanMap) {
dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
dependentBeans = new LinkedHashSet<String>(8);
this.dependentBeanMap.put(canonicalName, dependentBeans);
}
dependentBeans.add(dependentBeanName);
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
if (dependenciesForBean == null) {
dependenciesForBean = new LinkedHashSet<String>(8);
this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
}
dependenciesForBean.add(canonicalName);
}
} /**
* Determine whether the specified dependent bean has been registered as
* dependent on the given bean or on any of its transitive dependencies.
* 判断2个bean是否有依赖关系
*
* @param beanName the name of the bean to check
* @param dependentBeanName the name of the dependent bean
* @since 4.0
*/
protected boolean isDependent(String beanName, String dependentBeanName) {
return isDependent(beanName, dependentBeanName, null);
} /**
* 判断2个bean是否有依赖关系,A中有B,B中有C,那C依赖A是true.
* @param beanName
* @param dependentBeanName
* @param alreadySeen
* @return
*/
private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {
String canonicalName = canonicalName(beanName);
if (alreadySeen != null && alreadySeen.contains(beanName)) {
return false;
}
// canonicalName是C dependentBeans是B
Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
if (dependentBeans == null) {
return false;
}
if (dependentBeans.contains(dependentBeanName)) {
return true;
}
// 第一轮没找到A只找到包含B的一个set.所以再便利这个set.去看这个set里的bean是否依赖A,但是可能会有循环引用.所以找过的bean需要记录,不需要再找
for (String transitiveDependency : dependentBeans) {
if (alreadySeen == null) {
alreadySeen = new HashSet<String>();
}
alreadySeen.add(beanName); // 已经找过的bean放到这里.C已经找过了.
if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) { // 递归调用,判断B是否依赖A,是true.而C依赖B,所以C依赖A
return true;
}
}
return false;
} /**
* Determine whether a dependent bean has been registered for the given name.
*
* @param beanName the name of the bean to check
*/
protected boolean hasDependentBean(String beanName) {
return this.dependentBeanMap.containsKey(beanName);
} /**
* Return the names of all beans which depend on the specified bean, if any.
*
* @param beanName the name of the bean
* @return the array of dependent bean names, or an empty array if none
*/
public String[] getDependentBeans(String beanName) {
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
return new String[0];
}
return StringUtils.toStringArray(dependentBeans);
} /**
* Return the names of all beans that the specified bean depends on, if any.
*
* @param beanName the name of the bean
* @return the array of names of beans which the bean depends on,
* or an empty array if none
*/
public String[] getDependenciesForBean(String beanName) {
Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(beanName);
if (dependenciesForBean == null) {
return new String[0];
}
return dependenciesForBean.toArray(new String[dependenciesForBean.size()]);
} /**
* 销毁单例bean
*/
public void destroySingletons() {
if (logger.isDebugEnabled()) {
logger.debug("Destroying singletons in " + this);
}
// 设置正在销毁的标志
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
} String[] disposableBeanNames;
synchronized (this.disposableBeans) {
disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
}
// 取出所有disposableBeans然后调用每个bean都调用相应的销毁方法
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
} // 所有缓存清空
this.containedBeanMap.clear();
this.dependentBeanMap.clear();
this.dependenciesForBeanMap.clear(); synchronized (this.singletonObjects) {
this.singletonObjects.clear();
this.singletonFactories.clear();
this.earlySingletonObjects.clear();
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
} /**
* Destroy the given bean. Delegates to {@code destroyBean}
* if a corresponding disposable bean instance is found.
*
* @param beanName the name of the bean
* @see #destroyBean
*/
public void destroySingleton(String beanName) {
// Remove a registered singleton of the given name, if any.
removeSingleton(beanName); // Destroy the corresponding DisposableBean instance.
DisposableBean disposableBean;
synchronized (this.disposableBeans) {
disposableBean = (DisposableBean) this.disposableBeans.remove(beanName);
}
destroyBean(beanName, disposableBean);
} /**
* Destroy the given bean. Must destroy beans that depend on the given
* bean before the bean itself. Should not throw any exceptions.
*
* @param beanName the name of the bean
* @param bean the bean instance to destroy
*/
protected void destroyBean(String beanName, DisposableBean bean) {
// Trigger destruction of dependent beans first...
// 销毁1个bean的时候需要按顺序,先销毁引用她的bean,再销毁他自己
Set<String> dependencies = this.dependentBeanMap.remove(beanName);
if (dependencies != null) {
if (logger.isDebugEnabled()) {
logger.debug("Retrieved dependent beans for bean '" + beanName + "': " + dependencies);
}
for (String dependentBeanName : dependencies) {
//对于每个引用这个bean的所有bean,先销毁他们,再销毁当前这个beanName对应的bean,A中有B需要先销毁A
destroySingleton(dependentBeanName);
}
} // Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy(); // DisposableBean接口的方法
} catch (Throwable ex) {
logger.error("Destroy method on bean with name '" + beanName + "' threw an exception", ex);
}
} // Trigger destruction of contained beans...
// 对于内部bean也一样,先销毁外部的bean
Set<String> containedBeans = this.containedBeanMap.remove(beanName);
if (containedBeans != null) {
for (String containedBeanName : containedBeans) {
destroySingleton(containedBeanName);
}
} // Remove destroyed bean from other beans' dependencies.
// 销毁了这个bean,那dependentBeanMap中如果其他bean依赖这个bean,就都可以移除这个bean的引用.比如A中有B和C类.destroyB的时候需要先destroy A
// 那destroy A了以后因为C也依赖A.所以也要把dependentBeanMap的key c 对应的vaalue A也删除,不然下次删除C的时候又要删除A.这样就重复destroy A了.
synchronized (this.dependentBeanMap) {
for (Iterator<Map.Entry<String, Set<String>>> it = this.dependentBeanMap.entrySet().iterator(); it.hasNext(); ) {
Map.Entry<String, Set<String>> entry = it.next();
Set<String> dependenciesToClean = entry.getValue();
dependenciesToClean.remove(beanName);
if (dependenciesToClean.isEmpty()) {
it.remove();
}
}
} // Remove destroyed bean's prepared dependency information.
this.dependenciesForBeanMap.remove(beanName);
} /**
* Exposes the singleton mutex to subclasses and external collaborators.
* <p>Subclasses should synchronize on the given Object if they perform
* any sort of extended singleton creation phase. In particular, subclasses
* should <i>not</i> have their own mutexes involved in singleton creation,
* to avoid the potential for deadlocks in lazy-init situations.
*/
public final Object getSingletonMutex() {
return this.singletonObjects;
} }
FactoryBeanRegistrySupport
这个类基本上和它的父类DefaultSingletonBeanRegistry功能差不多.就是多了1个叫做factoryBeanObjectCache的map去缓存FactoryBean生成的bean...代码写法都大同小异..我想分享下期中的1个方法
/**
* Obtain an object to expose from the given FactoryBean.
*
* @param factory the FactoryBean instance
* @param beanName the name of the bean
* @param shouldPostProcess whether the bean is subject to post-processing
* @return the object obtained from the FactoryBean
* @throws BeanCreationException if FactoryBean object creation failed
* @see org.springframework.beans.factory.FactoryBean#getObject()
*/
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) { // FactoryBean返回的对象是单例并且FactoryBean(不是返回的对象)这个bean已经在缓存中了
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName); // 从缓存里拿FactoryBean的返回对象
if (object == null) { // 没缓存的话
object = doGetObjectFromFactoryBean(factory, beanName); // 就重新生成
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName); // 不懂为什么上面去过一次是null了需要再取几次...什么时候会发生呢?
if (alreadyThere != null) {
object = alreadyThere;
} else {
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName); // 后置处理
} catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
} else { // 不是单例,或者第一次调用FactoryBean不再缓存中
Object object = doGetObjectFromFactoryBean(factory, beanName); // 从FactoryBean里生成
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName); // 后置处理
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
对比它的父类里的一些map....
factoryBeanObjectCache里存的是BeanFactory的getObject返回的对象.
singletonObjects里存一般的单例和BeanFactory对象.
然后不管是BeanFactory还是BeanFactory返回的对象.beanname都是不带&,这点和使用BeanFactory的getBean方法不太一样...等看到后面的BF可能就清楚为什么了.
另外postProcessObjectFromFactoryBean这个方法在当前类里仅仅返回传入参数object.但是是个protected的方法,子类肯定会去重写的.这个方法不出意外应该就是BeanPostProcessor参与Spring声明周期的地方(对于FactoryBean来说).
一个小测试:
package spring.bf; import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:test-application-context.xml")
public class FactoryBeanRegistrySupportTest { @Autowired
@Qualifier("factoryBeanRegistrySupportTest_FactoryBean")
Object o; /**
* 测试BeanFactory和BeanPostProcessor
*/
@Test
public void test1() {
System.out.println(o);
}
} @Component
class FactoryBeanRegistrySupportTest_FactoryBean implements FactoryBean<Object> { private Object a = new Object(); @Override
public Object getObject() throws Exception {
return a;
} @Override
public Class<?> getObjectType() {
return Object.class;
} @Override
public boolean isSingleton() {
return true;
}
} @Component
class FactoryBeanRegistrySupportTest_PostProcess implements BeanPostProcessor { private static final String name = "factoryBeanRegistrySupportTest_FactoryBean"; @Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals(name)) {
System.out.println("postProcessBeforeInitialization ->" + beanName);
}
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals(name)) {
System.out.println("postProcessAfterInitialization ->" + beanName);
}
return bean;
}
}
输出:
postProcessBeforeInitialization ->factoryBeanRegistrySupportTest_FactoryBean 这个是FactoryBean作为单例被new的时候做的
postProcessAfterInitialization ->factoryBeanRegistrySupportTest_FactoryBean 这个是FactoryBean作为单例被new的时候做的
postProcessAfterInitialization ->factoryBeanRegistrySupportTest_FactoryBean 这个是FactoryBean的getObject返回的对象做的
java.lang.Object@f1e3986 输出getObject返回的对象
那么为什么FactoryBean的返回对象不要做postProcessBeforeInitialization,只做了postProcessAfterInitialization 呢??? 为什么这样设定??? 不太懂.
我觉得.可能是其他bean的afterProperties可能会扫描一些特性的bean做处理..这里工厂返回的bean肯定没有被之前扫描到.而postProcessBeforeInitialization是要在afterProperties之前做的(对于单个bean来说).所以这里不再执行.
AbstractBeanFactory
/*
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.beans.factory.support; import org.springframework.beans.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.*;
import org.springframework.core.DecoratingClassLoader;
import org.springframework.core.NamedThreadLocal;
import org.springframework.core.convert.ConversionService;
import org.springframework.util.*; import java.beans.PropertyEditor;
import java.security.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap; /**
* Abstract base class for {@link org.springframework.beans.factory.BeanFactory}
* implementations, providing the full capabilities of the
* {@link org.springframework.beans.factory.config.ConfigurableBeanFactory} SPI.
* Does <i>not</i> assume a listable bean factory: can therefore also be used
* as base class for bean factory implementations which obtain bean definitions
* from some backend resource (where bean definition access is an expensive operation).
* <p>
* <p>This class provides a singleton cache (through its base class
* {@link org.springframework.beans.factory.support.DefaultSingletonBeanRegistry},
* singleton/prototype determination, {@link org.springframework.beans.factory.FactoryBean}
* handling, aliases, bean definition merging for child bean definitions,
* and bean destruction ({@link org.springframework.beans.factory.DisposableBean}
* interface, custom destroy methods). Furthermore, it can manage a bean factory
* hierarchy (delegating to the parent in case of an unknown bean), through implementing
* the {@link org.springframework.beans.factory.HierarchicalBeanFactory} interface.
* <p>
* <p>The main template methods to be implemented by subclasses are
* {@link #getBeanDefinition} and {@link #createBean}, retrieving a bean definition
* for a given bean name and creating a bean instance for a given bean definition,
* respectively. Default implementations of those operations can be found in
* {@link DefaultListableBeanFactory} and {@link AbstractAutowireCapableBeanFactory}.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Costin Leau
* @author Chris Beams
* @see #getBeanDefinition
* @see #createBean
* @see AbstractAutowireCapableBeanFactory#createBean
* @see DefaultListableBeanFactory#getBeanDefinition
* @since 15 April 2001
*/
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory { /**
* Parent bean factory, for bean inheritance support
*/
private BeanFactory parentBeanFactory; /**
* ClassLoader to resolve bean class names with, if necessary
*/
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); /**
* ClassLoader to temporarily resolve bean class names with, if necessary
*/
private ClassLoader tempClassLoader; /**
* Whether to cache bean metadata or rather reobtain it for every access
*/
private boolean cacheBeanMetadata = true; /**
* Resolution strategy for expressions in bean definition values
*/
private BeanExpressionResolver beanExpressionResolver; /**
* Spring ConversionService to use instead of PropertyEditors
*/
private ConversionService conversionService; /**
* Custom PropertyEditorRegistrars to apply to the beans of this factory
*/
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars =
new LinkedHashSet<PropertyEditorRegistrar>(4); /**
* A custom TypeConverter to use, overriding the default PropertyEditor mechanism
*/
private TypeConverter typeConverter; /**
* Custom PropertyEditors to apply to the beans of this factory
*/
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors =
new HashMap<Class<?>, Class<? extends PropertyEditor>>(4); /**
* String resolvers to apply e.g. to annotation attribute values
*/
private final List<StringValueResolver> embeddedValueResolvers = new LinkedList<StringValueResolver>(); /**
* BeanPostProcessors to apply in createBean
*/
private final List<BeanPostProcessor> beanPostProcessors = new ArrayList<BeanPostProcessor>(); /**
* Indicates whether any InstantiationAwareBeanPostProcessors have been registered
*/
private boolean hasInstantiationAwareBeanPostProcessors; /**
* Indicates whether any DestructionAwareBeanPostProcessors have been registered
*/
private boolean hasDestructionAwareBeanPostProcessors; /**
* Map from scope identifier String to corresponding Scope
*/
private final Map<String, Scope> scopes = new LinkedHashMap<String, Scope>(8); /**
* Security context used when running with a SecurityManager
*/
private SecurityContextProvider securityContextProvider; /**
* Map from bean name to merged RootBeanDefinition
*/
private final Map<String, RootBeanDefinition> mergedBeanDefinitions =
new ConcurrentHashMap<String, RootBeanDefinition>(64); /**
* Names of beans that have already been created at least once
*/
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<String, Boolean>(64)); /**
* Names of beans that are currently in creation
*/
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
new NamedThreadLocal<Object>("Prototype beans currently in creation"); /**
* Create a new AbstractBeanFactory.
*/
public AbstractBeanFactory() {
} /**
* Create a new AbstractBeanFactory with the given parent.
*
* @param parentBeanFactory parent bean factory, or {@code null} if none
* @see #getBean
*/
public AbstractBeanFactory(BeanFactory parentBeanFactory) {
this.parentBeanFactory = parentBeanFactory;
} //---------------------------------------------------------------------
// Implementation of BeanFactory interface
//--------------------------------------------------------------------- @Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
} @Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
} @Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
} /**
* Return an instance, which may be shared or independent, of the specified bean.
*
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
} /**
* Return an instance, which may be shared or independent, of the specified bean.
*
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 别名转化成bean的名字,同时有&的话直接去掉
final String beanName = transformedBeanName(name);
Object bean; // Eagerly check singleton cache for manually registered singletons.
// 可能会是FactoryBean
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
} else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 如果是FactoryBean就调用getObject,否则就返回那个bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else { // 有可能是prototype bean
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
// 如果当前线程已经在创建个bean了.就抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
} // Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果这个bean的配置定义在父BF中的,即当前BF没有这个bean的配置信息
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
// 转化别名成bean的实际名字,但是不会去掉&
String nameToLookup = originalBeanName(name);
// 调用父BF的getBean方法去获取bean.
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
} if (!typeCheckOnly) {
// 标记这个bean已被创建
markBeanAsCreated(beanName);
} try {
// 获取BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 检测这个bean是不是abstract的
checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on.
// A中有B,C,dependsOn=B,C
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) { // B和C
// 如果dependsOnBean中有beanName域.而mbd.getDependsOn();说明beanName中有dependsOnBean,所以是相互依赖
if (isDependent(beanName, dependsOnBean)) { // 为true说明B,C中也有A,而外层的mbd.getDependsOn();说明A中有B,C,所以循环引用
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
// beanName中有dependsOnBean,beanName依赖于dependsOnBean
registerDependentBean(dependsOnBean, beanName);
// 先初始化成员域的bean
getBean(dependsOnBean);
}
} // Create bean instance.
// 如果是单例
if (mbd.isSingleton()) {
// 获取这个bean,没创建就创建
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
}
});
// 如果是FactoryBean就调用getObject,否则就返回那个bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) { // 如果是原型bean
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
// 记录正在创建的原型bean,这个bean和线程绑定
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
// 创建完毕,移除这个标记
afterPrototypeCreation(beanName);
}
// 如果是FactoryBean就调用getObject,否则就返回那个bean
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
// 既不是单例又不是原型
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; " +
"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
// 创建出错.
// 因为之前调用过markBeanAsCreated(beanName);标记过bean被创建,实际是失败的,所以要移除这个标记
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
} // Check if required type matches the type of the actual bean instance.
// 讲前面得到的bean进行类型转化并返回
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
} catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type [" +
ClassUtils.getQualifiedName(requiredType) + "]", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
} @Override
public boolean containsBean(String name) {
String beanName = transformedBeanName(name);
if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
// &开头或者是FactoryBean的实例
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
}
// Not found -> check parent.
// 本BF找不到就找父类的
BeanFactory parentBeanFactory = getParentBeanFactory();
return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
} @Override
public boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name); // 去掉&并且将alias转化成真正的beanname Object beanInstance = getSingleton(beanName, false); // 取到singleton
if (beanInstance != null) {
if (beanInstance instanceof FactoryBean) { // 如果bean是FactoryBean.
// &开头为true(取工厂bean)或者FactoryBean的isSingleton返回为true(不是&开头,取工厂的getObject返回)
return (BeanFactoryUtils.isFactoryDereference(name) || ((FactoryBean<?>) beanInstance).isSingleton());
} else { // 不是工厂bean的情况下,不是&开头返回ture,就是最一般的单例bean.
return !BeanFactoryUtils.isFactoryDereference(name);
}
} else if (containsSingleton(beanName)) { // 不知道什么时候会进,getSingleton,但是containsSingleton为true.可能是abstract的bean吧
return true;
} else {
// No singleton instance found -> check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory -> delegate to parent.
// 本BF没有这个bean的定义的话可以去找父类的.
return parentBeanFactory.isSingleton(originalBeanName(name));
} // 合并父类和本身的bean定义
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // In case of FactoryBean, return singleton status of created object if not a dereference.
if (mbd.isSingleton()) { // 定义中是单例,在判断是不是工厂
if (isFactoryBean(beanName, mbd)) { // 是工厂的话并且是不带&的话需要调用工厂的isSingleton方法
if (BeanFactoryUtils.isFactoryDereference(name)) {
return true;
}
FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
return factoryBean.isSingleton();
} else { // 不是工厂bean就是true
return !BeanFactoryUtils.isFactoryDereference(name);
}
} else {
return false;
}
}
} @Override
public boolean isPrototype(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name); BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory -> delegate to parent.
// 本BF中没有这个bean的定义就找父工厂
return parentBeanFactory.isPrototype(originalBeanName(name));
} // 合并父BF和本BF得到bean的定义
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
if (mbd.isPrototype()) { // bean的定义是原型,并且取不带&的bean,那就是原型对象为true,如果取&的bean,那需要返回的是工厂,如果是FactoryBean
// In case of FactoryBean, return singleton status of created object if not a dereference.
return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName, mbd));
} else {
// Singleton or scoped - not a prototype.
// However, FactoryBean may still produce a prototype object...
// 如果是&开头取工厂就直接返回false
if (BeanFactoryUtils.isFactoryDereference(name)) {
return false;
}
// 不是&开头的话要看工厂的isSingleton或者isPrototype
if (isFactoryBean(beanName, mbd)) {
final FactoryBean<?> factoryBean = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
!factoryBean.isSingleton());
}
}, getAccessControlContext());
} else {
return ((factoryBean instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factoryBean).isPrototype()) ||
!factoryBean.isSingleton());
}
} else {
return false;
}
}
} @Override
public boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name);
Class<?> typeToMatch = (targetType != null ? targetType : Object.class); // Check manually registered singletons.
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance instanceof FactoryBean) {
if (!BeanFactoryUtils.isFactoryDereference(name)) { // 取工厂的返回
Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
return (type != null && ClassUtils.isAssignable(typeToMatch, type));
} else { // 取工厂bean
return ClassUtils.isAssignableValue(typeToMatch, beanInstance);
}
} else { // 取一般的bean
return !BeanFactoryUtils.isFactoryDereference(name) &&
ClassUtils.isAssignableValue(typeToMatch, beanInstance);
}
} else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
// null instance registered
return false;
} else {
// No singleton instance found -> check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory -> delegate to parent.
return parentBeanFactory.isTypeMatch(originalBeanName(name), targetType);
} // Retrieve corresponding bean definition.
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); Class<?>[] typesToMatch = (FactoryBean.class.equals(typeToMatch) ?
new Class<?>[]{typeToMatch} : new Class<?>[]{FactoryBean.class, typeToMatch}); // Check decorated bean definition, if any: We assume it'll be easier
// to determine the decorated bean's type than the proxy's type.
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return typeToMatch.isAssignableFrom(targetClass);
}
} Class<?> beanType = predictBeanType(beanName, mbd, typesToMatch);
if (beanType == null) {
return false;
} // Check bean class whether we're dealing with a FactoryBean.
if (FactoryBean.class.isAssignableFrom(beanType)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not the factory class.
beanType = getTypeForFactoryBean(beanName, mbd);
if (beanType == null) {
return false;
}
}
} else if (BeanFactoryUtils.isFactoryDereference(name)) {
// Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
// type but we nevertheless are being asked to dereference a FactoryBean...
// Let's check the original bean class and proceed with it if it is a FactoryBean.
beanType = predictBeanType(beanName, mbd, FactoryBean.class);
if (beanType == null || !FactoryBean.class.isAssignableFrom(beanType)) {
return false;
}
} return typeToMatch.isAssignableFrom(beanType);
}
} @Override
public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name); // Check manually registered singletons.
Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
} else {
return beanInstance.getClass();
}
} else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
// null instance registered
return null;
} else {
// No singleton instance found -> check bean definition.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// No bean definition found in this factory -> delegate to parent.
return parentBeanFactory.getType(originalBeanName(name));
} RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Check decorated bean definition, if any: We assume it'll be easier
// to determine the decorated bean's type than the proxy's type.
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
return targetClass;
}
} Class<?> beanClass = predictBeanType(beanName, mbd); // Check bean class whether we're dealing with a FactoryBean.
if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
if (!BeanFactoryUtils.isFactoryDereference(name)) {
// If it's a FactoryBean, we want to look at what it creates, not at the factory class.
return getTypeForFactoryBean(beanName, mbd);
} else {
return beanClass;
}
} else {
return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
}
}
} /**
* 覆盖了父类方法,增加了对FactoryBean的支持
*
* @param name
* @return
*/
@Override
public String[] getAliases(String name) {
String beanName = transformedBeanName(name);
List<String> aliases = new ArrayList<String>();
boolean factoryPrefix = name.startsWith(FACTORY_BEAN_PREFIX);
String fullBeanName = beanName;
if (factoryPrefix) {
fullBeanName = FACTORY_BEAN_PREFIX + beanName;
}
if (!fullBeanName.equals(name)) {
aliases.add(fullBeanName);
}
String[] retrievedAliases = super.getAliases(beanName);
for (String retrievedAlias : retrievedAliases) {
String alias = (factoryPrefix ? FACTORY_BEAN_PREFIX : "") + retrievedAlias;
if (!alias.equals(name)) {
aliases.add(alias);
}
}
if (!containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null) {
aliases.addAll(Arrays.asList(parentBeanFactory.getAliases(fullBeanName)));
}
}
return StringUtils.toStringArray(aliases);
} //---------------------------------------------------------------------
// Implementation of HierarchicalBeanFactory interface
//--------------------------------------------------------------------- @Override
public BeanFactory getParentBeanFactory() {
return this.parentBeanFactory;
} @Override
public boolean containsLocalBean(String name) {
String beanName = transformedBeanName(name);
return ((containsSingleton(beanName) || containsBeanDefinition(beanName)) &&
(!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(beanName)));
} //---------------------------------------------------------------------
// Implementation of ConfigurableBeanFactory interface
//--------------------------------------------------------------------- @Override
public void setParentBeanFactory(BeanFactory parentBeanFactory) {
if (this.parentBeanFactory != null && this.parentBeanFactory != parentBeanFactory) {
throw new IllegalStateException("Already associated with parent BeanFactory: " + this.parentBeanFactory);
}
this.parentBeanFactory = parentBeanFactory;
} @Override
public void setBeanClassLoader(ClassLoader beanClassLoader) {
this.beanClassLoader = (beanClassLoader != null ? beanClassLoader : ClassUtils.getDefaultClassLoader());
} @Override
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
} @Override
public void setTempClassLoader(ClassLoader tempClassLoader) {
this.tempClassLoader = tempClassLoader;
} @Override
public ClassLoader getTempClassLoader() {
return this.tempClassLoader;
} @Override
public void setCacheBeanMetadata(boolean cacheBeanMetadata) {
this.cacheBeanMetadata = cacheBeanMetadata;
} @Override
public boolean isCacheBeanMetadata() {
return this.cacheBeanMetadata;
} @Override
public void setBeanExpressionResolver(BeanExpressionResolver resolver) {
this.beanExpressionResolver = resolver;
} @Override
public BeanExpressionResolver getBeanExpressionResolver() {
return this.beanExpressionResolver;
} @Override
public void setConversionService(ConversionService conversionService) {
this.conversionService = conversionService;
} @Override
public ConversionService getConversionService() {
return this.conversionService;
} @Override
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");
this.propertyEditorRegistrars.add(registrar);
} /**
* Return the set of PropertyEditorRegistrars.
*/
public Set<PropertyEditorRegistrar> getPropertyEditorRegistrars() {
return this.propertyEditorRegistrars;
} @Override
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
Assert.notNull(requiredType, "Required type must not be null");
Assert.isAssignable(PropertyEditor.class, propertyEditorClass);
this.customEditors.put(requiredType, propertyEditorClass);
} @Override
public void copyRegisteredEditorsTo(PropertyEditorRegistry registry) {
registerCustomEditors(registry);
} /**
* Return the map of custom editors, with Classes as keys and PropertyEditor classes as values.
*/
public Map<Class<?>, Class<? extends PropertyEditor>> getCustomEditors() {
return this.customEditors;
} @Override
public void setTypeConverter(TypeConverter typeConverter) {
this.typeConverter = typeConverter;
} /**
* Return the custom TypeConverter to use, if any.
*
* @return the custom TypeConverter, or {@code null} if none specified
*/
protected TypeConverter getCustomTypeConverter() {
return this.typeConverter;
} @Override
public TypeConverter getTypeConverter() {
TypeConverter customConverter = getCustomTypeConverter();
if (customConverter != null) {
return customConverter;
} else {
// Build default TypeConverter, registering custom editors.
SimpleTypeConverter typeConverter = new SimpleTypeConverter();
typeConverter.setConversionService(getConversionService());
registerCustomEditors(typeConverter);
return typeConverter;
}
} @Override
public void addEmbeddedValueResolver(StringValueResolver valueResolver) {
Assert.notNull(valueResolver, "StringValueResolver must not be null");
this.embeddedValueResolvers.add(valueResolver);
} @Override
public String resolveEmbeddedValue(String value) {
String result = value;
for (StringValueResolver resolver : this.embeddedValueResolvers) {
if (result == null) {
return null;
}
result = resolver.resolveStringValue(result);
}
return result;
} @Override
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;
}
} @Override
public int getBeanPostProcessorCount() {
return this.beanPostProcessors.size();
} /**
* Return the list of BeanPostProcessors that will get applied
* to beans created with this factory.
*/
public List<BeanPostProcessor> getBeanPostProcessors() {
return this.beanPostProcessors;
} /**
* Return whether this factory holds a InstantiationAwareBeanPostProcessor
* that will get applied to singleton beans on shutdown.
*
* @see #addBeanPostProcessor
* @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor
*/
protected boolean hasInstantiationAwareBeanPostProcessors() {
return this.hasInstantiationAwareBeanPostProcessors;
} /**
* Return whether this factory holds a DestructionAwareBeanPostProcessor
* that will get applied to singleton beans on shutdown.
*
* @see #addBeanPostProcessor
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
*/
protected boolean hasDestructionAwareBeanPostProcessors() {
return this.hasDestructionAwareBeanPostProcessors;
} @Override
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 (SCOPE_SINGLETON.equals(scopeName) || SCOPE_PROTOTYPE.equals(scopeName)) {
throw new IllegalArgumentException("Cannot replace existing scopes 'singleton' and 'prototype'");
}
Scope previous = this.scopes.put(scopeName, scope);
if (previous != null && previous != scope) {
if (logger.isInfoEnabled()) {
logger.info("Replacing scope '" + scopeName + "' from [" + previous + "] to [" + scope + "]");
}
} else {
if (logger.isDebugEnabled()) {
logger.debug("Registering scope '" + scopeName + "' with implementation [" + scope + "]");
}
}
} @Override
public String[] getRegisteredScopeNames() {
return StringUtils.toStringArray(this.scopes.keySet());
} @Override
public Scope getRegisteredScope(String scopeName) {
Assert.notNull(scopeName, "Scope identifier must not be null");
return this.scopes.get(scopeName);
} /**
* Set the security context provider for this bean factory. If a security manager
* is set, interaction with the user code will be executed using the privileged
* of the provided security context.
*/
public void setSecurityContextProvider(SecurityContextProvider securityProvider) {
this.securityContextProvider = securityProvider;
} /**
* Delegate the creation of the access control context to the
* {@link #setSecurityContextProvider SecurityContextProvider}.
*/
@Override
public AccessControlContext getAccessControlContext() {
return (this.securityContextProvider != null ?
this.securityContextProvider.getAccessControlContext() :
AccessController.getContext());
} @Override
public void copyConfigurationFrom(ConfigurableBeanFactory otherFactory) {
Assert.notNull(otherFactory, "BeanFactory must not be null");
setBeanClassLoader(otherFactory.getBeanClassLoader());
setCacheBeanMetadata(otherFactory.isCacheBeanMetadata());
setBeanExpressionResolver(otherFactory.getBeanExpressionResolver());
if (otherFactory instanceof AbstractBeanFactory) {
AbstractBeanFactory otherAbstractFactory = (AbstractBeanFactory) otherFactory;
this.customEditors.putAll(otherAbstractFactory.customEditors);
this.propertyEditorRegistrars.addAll(otherAbstractFactory.propertyEditorRegistrars);
this.beanPostProcessors.addAll(otherAbstractFactory.beanPostProcessors);
this.hasInstantiationAwareBeanPostProcessors = this.hasInstantiationAwareBeanPostProcessors ||
otherAbstractFactory.hasInstantiationAwareBeanPostProcessors;
this.hasDestructionAwareBeanPostProcessors = this.hasDestructionAwareBeanPostProcessors ||
otherAbstractFactory.hasDestructionAwareBeanPostProcessors;
this.scopes.putAll(otherAbstractFactory.scopes);
this.securityContextProvider = otherAbstractFactory.securityContextProvider;
} else {
setTypeConverter(otherFactory.getTypeConverter());
}
} /**
* Return a 'merged' BeanDefinition for the given bean name,
* merging a child bean definition with its parent if necessary.
* <p>This {@code getMergedBeanDefinition} considers bean definition
* in ancestors as well.
*
* @param name the name of the bean to retrieve the merged definition for
* (may be an alias)
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
@Override
public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
String beanName = transformedBeanName(name); // Efficiently check whether bean definition exists in this factory.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
}
// Resolve merged bean definition locally.
return getMergedLocalBeanDefinition(beanName);
} @Override
public boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException {
String beanName = transformedBeanName(name); Object beanInstance = getSingleton(beanName, false);
if (beanInstance != null) {
return (beanInstance instanceof FactoryBean);
} else if (containsSingleton(beanName)) {
// 可能这个bean不允许被创建(abstract的bean)?
// null instance registered
return false;
} // No singleton instance found -> check bean definition.
if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
// No bean definition found in this factory -> delegate to parent.
// 本BF没有就找父类的
return ((ConfigurableBeanFactory) getParentBeanFactory()).isFactoryBean(name);
} return isFactoryBean(beanName, getMergedLocalBeanDefinition(beanName));
} @Override
public boolean isActuallyInCreation(String beanName) {
return (isSingletonCurrentlyInCreation(beanName) || isPrototypeCurrentlyInCreation(beanName));
} /**
* Return whether the specified prototype bean is currently in creation
* (within the current thread).
*
* @param beanName the name of the bean
*/
protected boolean isPrototypeCurrentlyInCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
return (curVal != null &&
(curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
} /**
* Callback before prototype creation.
* 将正在创建的额原型bean放到threadlocal中,1个原型bean的类在1个线程中只能有1个正在创建的实例
* <p>The default implementation register the prototype as currently in creation.
*
* @param beanName the name of the prototype about to be created
* @see #isPrototypeCurrentlyInCreation
*/
@SuppressWarnings("unchecked")
protected void beforePrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal == null) {
this.prototypesCurrentlyInCreation.set(beanName);
} else if (curVal instanceof String) {
Set<String> beanNameSet = new HashSet<String>(2);
beanNameSet.add((String) curVal);
beanNameSet.add(beanName);
this.prototypesCurrentlyInCreation.set(beanNameSet);
} else {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.add(beanName);
}
} /**
* Callback after prototype creation.
* 将之前线程变量中存着的正在创建的原型bean移除,因为已经创建完毕
* <p>The default implementation marks the prototype as not in creation anymore.
*
* @param beanName the name of the prototype that has been created
* @see #isPrototypeCurrentlyInCreation
*/
@SuppressWarnings("unchecked")
protected void afterPrototypeCreation(String beanName) {
Object curVal = this.prototypesCurrentlyInCreation.get();
if (curVal instanceof String) {
this.prototypesCurrentlyInCreation.remove();
} else if (curVal instanceof Set) {
Set<String> beanNameSet = (Set<String>) curVal;
beanNameSet.remove(beanName);
if (beanNameSet.isEmpty()) {
this.prototypesCurrentlyInCreation.remove();
}
}
} @Override
public void destroyBean(String beanName, Object beanInstance) {
destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
} /**
* Destroy the given bean instance (usually a prototype instance
* obtained from this factory) according to the given bean definition.
*
* @param beanName the name of the bean definition
* @param beanInstance the bean instance to destroy
* @param mbd the merged bean definition
*/
protected void destroyBean(String beanName, Object beanInstance, RootBeanDefinition mbd) {
new DisposableBeanAdapter(beanInstance, beanName, mbd, getBeanPostProcessors(), getAccessControlContext()).destroy();
} @Override
public void destroyScopedBean(String beanName) {
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
if (mbd.isSingleton() || mbd.isPrototype()) {
throw new IllegalArgumentException(
"Bean name '" + beanName + "' does not correspond to an object in a mutable scope");
}
String scopeName = mbd.getScope();
Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope SPI registered for scope '" + scopeName + "'");
}
Object bean = scope.remove(beanName);
if (bean != null) {
destroyBean(beanName, bean, mbd);
}
} //---------------------------------------------------------------------
// Implementation methods
//--------------------------------------------------------------------- /**
* Return the bean name, stripping out the factory dereference prefix if necessary,
* and resolving aliases to canonical names.
* 去掉&前缀,并且把alias->真正的beanname
*
* @param name the user-specified name
* @return the transformed bean name
*/
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
} /**
* Determine the original bean name, resolving locally defined aliases to canonical names.
*
* @param name the user-specified name
* @return the original bean name
*/
protected String originalBeanName(String name) {
String beanName = transformedBeanName(name);
if (name.startsWith(FACTORY_BEAN_PREFIX)) {
beanName = FACTORY_BEAN_PREFIX + beanName;
}
return beanName;
} /**
* Initialize the given BeanWrapper with the custom editors registered
* with this factory. To be called for BeanWrappers that will create
* and populate bean instances.
* <p>The default implementation delegates to {@link #registerCustomEditors}.
* Can be overridden in subclasses.
*
* @param bw the BeanWrapper to initialize
*/
protected void initBeanWrapper(BeanWrapper bw) {
bw.setConversionService(getConversionService());
registerCustomEditors(bw);
} /**
* Initialize the given PropertyEditorRegistry with the custom editors
* that have been registered with this BeanFactory.
* <p>To be called for BeanWrappers that will create and populate bean
* instances, and for SimpleTypeConverter used for constructor argument
* and factory method type conversion.
*
* @param registry the PropertyEditorRegistry to initialize
*/
protected void registerCustomEditors(PropertyEditorRegistry registry) {
PropertyEditorRegistrySupport registrySupport =
(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
if (registrySupport != null) {
registrySupport.useConfigValueEditors();
}
if (!this.propertyEditorRegistrars.isEmpty()) {
for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
try {
registrar.registerCustomEditors(registry);
} catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
if (isCurrentlyInCreation(bce.getBeanName())) {
if (logger.isDebugEnabled()) {
logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
"] failed because it tried to obtain currently created bean '" +
ex.getBeanName() + "': " + ex.getMessage());
}
onSuppressedException(ex);
continue;
}
}
throw ex;
}
}
}
if (!this.customEditors.isEmpty()) {
for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {
Class<?> requiredType = entry.getKey();
Class<? extends PropertyEditor> editorClass = entry.getValue();
registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass));
}
}
} /**
* Return a merged RootBeanDefinition, traversing the parent bean definition
* if the specified bean corresponds to a child bean definition.
* 有缓存直接缓存取,没有的话就合并自己的和父类的.
*
* @param beanName the name of the bean to retrieve the merged definition for
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
} /**
* Return a RootBeanDefinition for the given top-level bean, by merging with
* the parent if the given bean's definition is a child bean definition.
*
* @param beanName the name of the bean definition
* @param bd the original bean definition (Root/ChildBeanDefinition)
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException { return getMergedBeanDefinition(beanName, bd, null);
} /**
* Return a RootBeanDefinition for the given bean, by merging with the
* parent if the given bean's definition is a child bean definition.
*
* @param beanName the name of the bean definition
* @param bd the original bean definition (Root/ChildBeanDefinition)
* @param containingBd the containing bean definition in case of inner bean,
* or {@code null} in case of a top-level bean
* @return a (potentially merged) RootBeanDefinition for the given bean
* @throws BeanDefinitionStoreException in case of an invalid bean definition
*/
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, BeanDefinition containingBd)
throws BeanDefinitionStoreException { synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null; // Check with full lock now in order to enforce the same merged instance.
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
} if (mbd == null) {
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
} else {
mbd = new RootBeanDefinition(bd);
}
} else {
// Child bean definition: needs to be merged with parent.
BeanDefinition pbd;
try {
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
pbd = getMergedBeanDefinition(parentBeanName);
} else {
if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
} else {
throw new NoSuchBeanDefinitionException(bd.getParentName(),
"Parent name '" + bd.getParentName() + "' is equal to bean name '" + beanName +
"': cannot be resolved without an AbstractBeanFactory parent");
}
}
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
}
// Deep copy with overridden values.
mbd = new RootBeanDefinition(pbd);
mbd.overrideFrom(bd);
} // Set default singleton scope, if not configured before.
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
} // A bean contained in a non-singleton bean cannot be a singleton itself.
// Let's correct this on the fly here, since this might be the result of
// parent-child merging for the outer bean, in which case the original inner bean
// definition will not have inherited the merged outer bean's singleton status.
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
mbd.setScope(containingBd.getScope());
} // Only cache the merged bean definition if we're already about to create an
// instance of the bean, or at least have already created an instance before.
if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) {
this.mergedBeanDefinitions.put(beanName, mbd);
}
} return mbd;
}
} /**
* Check the given merged bean definition,
* potentially throwing validation exceptions.
*
* @param mbd the merged bean definition to check
* @param beanName the name of the bean
* @param args the arguments for bean creation, if any
* @throws BeanDefinitionStoreException in case of validation failure
*/
protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
throws BeanDefinitionStoreException { if (mbd.isAbstract()) {
throw new BeanIsAbstractException(beanName);
}
} /**
* Remove the merged bean definition for the specified bean,
* recreating it on next access.
*
* @param beanName the bean name to clear the merged definition for
*/
protected void clearMergedBeanDefinition(String beanName) {
this.mergedBeanDefinitions.remove(beanName);
} /**
* Resolve the bean class for the specified bean definition,
* resolving a bean class name into a Class reference (if necessary)
* and storing the resolved Class in the bean definition for further use.
*
* @param mbd the merged bean definition to determine the class for
* @param beanName the name of the bean (for error handling purposes)
* @param typesToMatch the types to match in case of internal type matching purposes
* (also signals that the returned {@code Class} will never be exposed to application code)
* @return the resolved bean class (or {@code null} if none)
* @throws CannotLoadBeanClassException if we failed to load the class
*/
protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
@Override
public Class<?> run() throws Exception {
return doResolveBeanClass(mbd, typesToMatch);
}
}, getAccessControlContext());
} else {
return doResolveBeanClass(mbd, typesToMatch);
}
} catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
} catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
} catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
} private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException {
if (!ObjectUtils.isEmpty(typesToMatch)) {
ClassLoader tempClassLoader = getTempClassLoader();
if (tempClassLoader != null) {
if (tempClassLoader instanceof DecoratingClassLoader) {
DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
for (Class<?> typeToMatch : typesToMatch) {
dcl.excludeClass(typeToMatch.getName());
}
}
String className = mbd.getBeanClassName();
return (className != null ? ClassUtils.forName(className, tempClassLoader) : null);
}
}
return mbd.resolveBeanClass(getBeanClassLoader());
} /**
* Evaluate the given String as contained in a bean definition,
* potentially resolving it as an expression.
*
* @param value the value to check
* @param beanDefinition the bean definition that the value comes from
* @return the resolved value
* @see #setBeanExpressionResolver
*/
protected Object evaluateBeanDefinitionString(String value, BeanDefinition beanDefinition) {
if (this.beanExpressionResolver == null) {
return value;
}
Scope scope = (beanDefinition != null ? getRegisteredScope(beanDefinition.getScope()) : null);
return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope));
} /**
* Predict the eventual bean type (of the processed bean instance) for the
* specified bean. Called by {@link #getType} and {@link #isTypeMatch}.
* Does not need to handle FactoryBeans specifically, since it is only
* supposed to operate on the raw bean type.
* <p>This implementation is simplistic in that it is not able to
* handle factory methods and InstantiationAwareBeanPostProcessors.
* It only predicts the bean type correctly for a standard bean.
* To be overridden in subclasses, applying more sophisticated type detection.
*
* @param beanName the name of the bean
* @param mbd the merged bean definition to determine the type for
* @param typesToMatch the types to match in case of internal type matching purposes
* (also signals that the returned {@code Class} will never be exposed to application code)
* @return the type of the bean, or {@code null} if not predictable
*/
protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
if (mbd.getFactoryMethodName() != null) {
return null;
}
return resolveBeanClass(mbd, beanName, typesToMatch);
} /**
* Check whether the given bean is defined as a {@link FactoryBean}.
*
* @param beanName the name of the bean
* @param mbd the corresponding bean definition
*/
protected boolean isFactoryBean(String beanName, RootBeanDefinition mbd) {
Class<?> beanType = predictBeanType(beanName, mbd, FactoryBean.class);
return (beanType != null && FactoryBean.class.isAssignableFrom(beanType));
} /**
* Determine the bean type for the given FactoryBean definition, as far as possible.
* Only called if there is no singleton instance registered for the target bean already.
* <p>The default implementation creates the FactoryBean via {@code getBean}
* to call its {@code getObjectType} method. Subclasses are encouraged to optimize
* this, typically by just instantiating the FactoryBean but not populating it yet,
* trying whether its {@code getObjectType} method already returns a type.
* If no type found, a full FactoryBean creation as performed by this implementation
* should be used as fallback.
*
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @return the type for the bean if determinable, or {@code null} else
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
* @see #getBean(String)
*/
protected Class<?> getTypeForFactoryBean(String beanName, RootBeanDefinition mbd) {
if (!mbd.isSingleton()) {
return null;
}
try {
FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
return getTypeForFactoryBean(factoryBean);
} catch (BeanCreationException ex) {
if (ex instanceof BeanCurrentlyInCreationException) {
if (logger.isDebugEnabled()) {
logger.debug("Bean currently in creation on FactoryBean type check: " + ex);
}
} else {
if (logger.isWarnEnabled()) {
logger.warn("Bean creation exception on FactoryBean type check: " + ex);
}
}
onSuppressedException(ex);
return null;
}
} /**
* Mark the specified bean as already created (or about to be created).
* <p>This allows the bean factory to optimize its caching for repeated
* creation of the specified bean.
*
* @param beanName the name of the bean
*/
protected void markBeanAsCreated(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
this.alreadyCreated.add(beanName);
}
} /**
* Perform appropriate cleanup of cached metadata after bean creation failed.
*
* @param beanName the name of the bean
*/
protected void cleanupAfterBeanCreationFailure(String beanName) {
this.alreadyCreated.remove(beanName);
} /**
* Determine whether the specified bean is eligible for having
* its bean definition metadata cached.
*
* @param beanName the name of the bean
* @return {@code true} if the bean's metadata may be cached
* at this point already
*/
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
return this.alreadyCreated.contains(beanName);
} /**
* Remove the singleton instance (if any) for the given bean name,
* but only if it hasn't been used for other purposes than type checking.
*
* @param beanName the name of the bean
* @return {@code true} if actually removed, {@code false} otherwise
*/
protected boolean removeSingletonIfCreatedForTypeCheckOnly(String beanName) {
if (!this.alreadyCreated.contains(beanName)) {
removeSingleton(beanName);
return true;
} else {
return false;
}
} /**
* Get the object for the given bean instance, either the bean
* instance itself or its created object in case of a FactoryBean.
*
* @param beanInstance the shared bean instance
* @param name name that may include factory dereference prefix
* @param beanName the canonical bean name
* @param mbd the merged bean definition
* @return the object to expose for the bean
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory.
// & 开头.但是这个bean却又不是FactoryBean.说明有问题. &都应该是factorybean
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
} // Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
// 不是FactoryBean直接返回这个bean,&开头的话也直接返回这个bean.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
} Object object = null;
if (mbd == null) {
// 说明这个bean是需要从FactoryBean的getObject方法中返回的.
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) { // 没有cache.需要生成的情况
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName); // 合并bean的定义
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic); // 不是合成的bean的定义的话这个bean从工厂中生成需要调用postProcessObjectFromFactoryBean方法对bean进行加工,我觉得是因为父类中的这些后置处理bean当前工厂里没有
}
return object;
} /**
* Determine whether the given bean name is already in use within this factory,
* i.e. whether there is a local bean or alias registered under this name or
* an inner bean created with this name.
*
* @param beanName the name to check
*/
public boolean isBeanNameInUse(String beanName) {
return isAlias(beanName) || containsLocalBean(beanName) || hasDependentBean(beanName);
} /**
* Determine whether the given bean requires destruction on shutdown.
* <p>The default implementation checks the DisposableBean interface as well as
* a specified destroy method and registered DestructionAwareBeanPostProcessors.
*
* @param bean the bean instance to check
* @param mbd the corresponding bean definition
* @see org.springframework.beans.factory.DisposableBean
* @see AbstractBeanDefinition#getDestroyMethodName()
* @see org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor
*/
protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
return (bean != null &&
(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || hasDestructionAwareBeanPostProcessors()));
} /**
* Add the given bean to the list of disposable beans in this factory,
* registering its DisposableBean interface and/or the given destroy method
* to be called on factory shutdown (if applicable). Only applies to singletons.
*
* @param beanName the name of the bean
* @param bean the bean instance
* @param mbd the bean definition for the bean
* @see RootBeanDefinition#isSingleton
* @see RootBeanDefinition#getDependsOn
* @see #registerDisposableBean
* @see #registerDependentBean
*/
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
} else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
} //---------------------------------------------------------------------
// Abstract methods to be implemented by subclasses
//--------------------------------------------------------------------- /**
* Check if this bean factory contains a bean definition with the given name.
* Does not consider any hierarchy this factory may participate in.
* Invoked by {@code containsBean} when no cached singleton instance is found.
* <p>Depending on the nature of the concrete bean factory implementation,
* this operation might be expensive (for example, because of directory lookups
* in external registries). However, for listable bean factories, this usually
* just amounts to a local hash lookup: The operation is therefore part of the
* public interface there. The same implementation can serve for both this
* template method and the public interface method in that case.
* 当前这个BF不算父类的.是否包含了给定的beanname对应的Definition
*
* @param beanName the name of the bean to look for
* @return if this bean factory contains a bean definition with the given name
* @see #containsBean
* @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
*/
protected abstract boolean containsBeanDefinition(String beanName); /**
* Return the bean definition for the given bean name.
* Subclasses should normally implement caching, as this method is invoked
* by this class every time bean definition metadata is needed.
* <p>Depending on the nature of the concrete bean factory implementation,
* this operation might be expensive (for example, because of directory lookups
* in external registries). However, for listable bean factories, this usually
* just amounts to a local hash lookup: The operation is therefore part of the
* public interface there. The same implementation can serve for both this
* template method and the public interface method in that case.
* 根据beanname获取BeanDefinition,子类实现,可以用缓存
*
* @param beanName the name of the bean to find a definition for
* @return the BeanDefinition for this prototype name (never {@code null})
* @throws org.springframework.beans.factory.NoSuchBeanDefinitionException if the bean definition cannot be resolved
* @throws BeansException in case of errors
* @see RootBeanDefinition
* @see ChildBeanDefinition
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory#getBeanDefinition
*/
protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException; /**
* Create a bean instance for the given merged bean definition (and arguments).
* The bean definition will already have been merged with the parent definition
* in case of a child definition.
* <p>All bean retrieval methods delegate to this method for actual bean creation.
*
* @param beanName the name of the bean
* @param mbd the merged bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a new instance of the bean
* @throws BeanCreationException if the bean could not be created
*/
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
throws BeanCreationException; }
一些方法加了注释,还有很多方法和其中的ifelse不明白为什么要这么写...
后续的一些逻辑要做实验才会明白了....