bean的加载
对于加载bean的功能,在spring中的调用方式为:
MyTestBean bean=(MyTestBean) bf.getBean(“myTestBean”)
//public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
//1.提取对应的beanName
final String beanName = transformedBeanName(name);
Object bean;
/**
* 检查缓存中或者实例工厂中是否有对应的实例
* 为什么首先使用这段代码呢?
* 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
* spring创建bean的原则是不等bean创建完成就会将创建bean的objectFactory提早曝光
* 也就是将ObjectFactory加入到缓存中,一旦下一个bean创建的时候需要依赖上一个bean则直接使用ObjectFactory
*/
//2.直接尝试从缓存中获取或者从singletonFactories中的ObjectFactory中获取(从缓存中获取单例bean)
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 + "'");
}
}
//3.返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法的实例
/**
* 无论是直接取单例的bean,还是创建单例、多例、自定义生命周期的bean,
* 都会经过bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);这个方法
* 主要是由于存在 诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法的实例 的情况
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//如果没有在缓存中获取到
else {
/**
* 只有在单例情况下才会尝试解决循环依赖;
* 原型模式情况下,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完成的时候因为对于B的创建再次返回创建A,造成循环依赖;
* 也就是下面的情况
* isPrototypeCurrentlyInCreation(beanName)为true
*/
//4.原型模式的依赖检查,只有在单例情况下才会尝试解决循环依赖,如果是原型模式,则抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//如果原型模式的bean中出现循环依赖,那么就会抛出异常,并且程序将不再向下执行
//如果是单例模式中有循环依赖,那么在后面创建单例模式的的bean时会针对循环依赖进行解决
//5.!containsBeanDefinition(beanName):如果beanDefinitionMap中也就是当前加载的XML配置文件所生成的在类中不包括beanName,则尝试从parentBeanFactory中检测
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取beanName
String nameToLookup = originalBeanName(name);
//递归到BeanFactory中寻找
if (args != null) {
//递归调用父Bean工厂的getBean(String name, Object... args)
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
//递归调用父Bean工厂的getBean(String name, Class<T> requiredType)
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//如果不是仅仅做类型检查而是创建创建bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//6. 将存储XML配置文件的GerenicBeanDefinition转换为RootBeanDefintion,转换的同时如果父类bean不为空的话,则会合并父类的属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//7.保证当前bean所依赖的bean的初始化(这里并不是循环依赖)
//dependsOn属性是在配置文件中设置的 <bean name="dao" class="" depends-on="database" ></bean>
String[] dependsOn = mbd.getDependsOn();
//若存在依赖则需要递归实例化依赖的bean
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
if (isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
//缓存依赖调用
registerDependentBean(dependsOnBean, beanName);
//实例化依赖的bean
getBean(dependsOnBean);
}
}
//8.当所依赖的bean被实例化后,接下来就可以根据scope的不同来创建bean了
// 单例模式的创建 (通过匿名内部类进行创建)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//多例模式的创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
//创建bean前将beanName放入prototypesCurrentlyInCreation中
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//创建bean前将beanName从prototypesCurrentlyInCreation中移除
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//指定scope上实例化bean
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
//9.检查需要的类型是否符合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;
}
逻辑分析:
(1) 转换对应beanName, 因为传入的参数可能是别名,也可能是beanFactory,所以需要进行一系列的解析
- 取出FactoryBean的修饰符,也就是如果name="&aa", 那么会首先取出& 而使name=“aa”
- 取指定alias所表示的最终beanName, 例如: 别名A指向名称为B的bean,则返回B;若别名A指向别名B,别名B又指向名称为C的bean,则返回C
(2) 尝试从缓存中加载单例
单例在spring的同一个容器中只会被创建一次, 后续再获取bean, 就直接从单例缓存中获取; 这里只是尝试加载, 首先尝试从缓存中加载, 如果加载失败, 则再次尝试从singltonFactories中加载; 因为创建单例bean时会出现依赖注入的情况, 而在创建依赖时为了避免依赖循环, 在spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光加入到缓存中, 一旦下一个bean创建时需要上一个依赖bean, 则直接使用ObjectFactory获取bean
(3) bean的实例化
如果从缓存中得到了bean 的原始状态, 则需要对bean进行实例化; 注意: 缓存中记录的只是最原始的bean状态, 并不一定是最终想要的bean; 例如: 需要对工厂bean进行处理, 那么这里得到的是工厂bean的初始状态, 但是我们需要的是工程bean中定义的factory-method方法返回的bean,而getObjectForBeanInstance就是完成这个工作的
(4) 原型模式的依赖检查
只有在到单例情况下才会尝试解决循环依赖, 如果在原型模式下出现依赖循环,则抛出异常; 如果存在A中有B的属性,B中有A的属性, 那么当依赖注入的时候, 就会产生当A还未创建完的时候,因为对于B的创建再次返回创建A,造成循环依赖
(5) 检测parentBeanFactory
!containsBeanDefinition(beanName): 如果beanDefinitionMap中也就是当前加载的XML配置文件所生成的在类中不包括beanName,则尝试从parentBeanFactory中检测,然后再去递归调用getBean方法
(6) 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
因为从XML配置文件中读取到的bean信息是存储在GenericBeanDefinition中的, 但是所有的bean后续处理都是针对于RootBeanDefinition的, 所以这里需要进行一个转换, 转换的同时如果父类不为空的话, 则会一并合并父类的属性
(7)寻找依赖
因为bean的初始化过程中很可能会用到某些属性,而某些属性很可能是动态配置的, 并且配置成依赖于其他的bean, 那么这个时候就有必要先加载依赖的bean, 所以在spring的加载顺序中, 在初始化某一个bean的时候会首先初始化这个bean所对应的依赖
(8) 针对不同的scope进行bean的创建; 默认的是singleton,spring会根据不同的配置进行不同的初始化策略
(9) 类型转换
1、FactoryBean的使用
一般情况下,spring通过反射机制利用bean的class属性指定事项类来实例化bean; 在某些情况下,实例化bean过程比较复杂, 如果按照传统的方式, 则需要在<bean>中提供大量的配置信息,配置方式的灵活性受限,这时采用编码的方法会得到一个简单的方案, spring为此提供一个org.springframework.beans.factory.FactoryBean工厂接口
FactoryBean接口的实现:
public interface FactoryBean<T> {
//返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中
T getObject() throws Exception;
//返回FactoryBean创建的bean类型
Class<?> getObjectType();
//返回由FactoryBean创建的bean实例的作用域是singleton还是prototype
boolean isSingleton();
}
逻辑分析:
当配置文件中的<bean>的class属性配置的实现类是factoryBean时,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean中getBean()方法返回的对象,相当于FactoryBea
n#getObject代理了一个getBean()方法;
例如:
public class Car {
private int maxSpeed;
private String brand;
private double price;
//set/get方法已省略
}
public class CarFactoryBean implements FactoryBean{
private String carInfo;
@Override
public Object getObject() throws Exception {
Car car = new Car();
String[] infos=carInfo.split(",");
car.setBrand(infos[0]);
car.setMaxSpeed(Integer.parseInt(infos[1]));
car.setPrice(Double.valueOf(infos[2]));
return car;
}
@Override
public Class getObjectType() {
return Car.class;
}
@Override
public boolean isSingleton() {
return false;
}
public String getCarInfo() {
return carInfo;
}
public void setCarInfo(String carInfo) {
this.carInfo = carInfo;
}
}
<bean id="car" class="com.text.CarFactoryBean" carInfo="超级跑车,400,20000000"/>
逻辑分析:
当调用getBean(“car”)时, spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时spring容器就调用接口方法CarFactoryBean#getObject()方法返回; 如果希望获取CarFactoryBean的实例, 则需要在使用getBean(beanName)方法时在beanName前显式的加上"&“前缀,例如: getBean(”&car")
2、缓存中获取到单例bean
单例在spring的同一个容器中只会被创建一次, 后续再获取bean, 就直接从单例缓存中获取; 这里只是尝试加载, 首先尝试从缓存中加载, 如果加载失败, 则再次尝试从singltonFactories中加载; 因为创建单例bean时会出现依赖注入的情况, 而在创建依赖时为了避免依赖循环, 在spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光加入到缓存中, 一旦下一个bean创建时需要上一个依赖bean, 则直接使用ObjectFactory获取bean
Object sharedInstance = getSingleton(beanName);
getSingleton(String beanName) 方法的实现:
//public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory
public Object getSingleton(String beanName) {
//参数true设置表示允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//1.检查缓存中是否存在实例,存在的话就直接返回
Object singletonObject = this.singletonObjects.get(beanName);
//2.如果缓存中没有,并且当前该实例在正在创建中,则锁定全局变量进行处理
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
//如果此bean正在加载,但是可以从earlySingletonObjects中获取,就返回该对象;否则进行创建(单例模式循环依赖解决)
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories(缓存中)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预先设定的getObject方法,创建singletonObject
singletonObject = singletonFactory.getObject();
//记录在earlySingletonObjects缓存中,避免循环依赖
//(不等bean创建完成就将创建bean的ObjectFactory提早曝光加入缓存中,一旦下一个bean创建需要依赖上一个bean,则直接使用ObjectFactory)
this.earlySingletonObjects.put(beanName, singletonObject);
//singletonFactories:用于保存BeanName和创建bean工厂之间的关系,与BeanName相关的bean已经被创建,所以需要从singletonFactories移除BeanName
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
逻辑分析:
首先尝试从singletonObjects里面获取实例, 如果获取不到再从earlySingletonObjects里面获取, 如果还获取不到, 在尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean, 并放到earlySingletonObjects里面去,并且从singletonFactories里面移除掉这个ObjectFactory;
- singletonObjects: (beanName -> bean实例) 保存BeanName和bean实例之间的关系
- singletonFactories: (beanName -> ObjectFactory), 保存BeanName和创建bean的工厂之间的关系
- earlySingletonObjects: (beanName ->ObjectFactory),保存BeanName和bean实例之间的关系, 与singletonObjects不同之处在于: 当一个单例bean被放到这里面之后, 那么当bean还在创建过程中, 就可以通过getBean方法获取到了, 其目的是用来检测循环引用
- registeredSingletons:用来保存当前所有已注册的bean
3、从bean的实例中获取对象
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
用于检测当前bean是否是FactoryBean类型的bean,如果是,那么需要调用该bean对应的factoryBean实例中的getObject()作为返回值
getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd)方法的实现:
//public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
//如果指定的name是工厂相关(以&为前缀),但是beanInstance却不是FactoryBean类型,则验证不通过
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
//如果beanInstance实例不是FactoryBean,或者指定名称是FactoryBean的解引用,也就是普通的bean调用,则直接返回当前的beanInstance实例
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
//!(beanInstance instanceof FactoryBean) 说明该bean为普通bean对象;
//BeanFactoryUtils.isFactoryDereference(name) 说明期望返回一个beanFactory对象
//用户只需要返回普通的bean对象或者FactoryBean对象
return beanInstance;
}
/**
* 如果我们创建的bean就是我们所需要的bean,那么以上两步就可以满足业务要求
*
* 如果需要使用FactoryBean的getObject()方法获取bean对象的话,需要下面的业务逻辑
*/
//加载FactoryBean(以下为通过beanFactory#getObject返回bean对象)
Object object = null;
if (mbd == null) {
//尝试从缓存中加载bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
//到这里已经明确知道beanInstance一定是FactoryBean类型
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
//containsBeanDefinition()方法检测beanDefinitionMap中是否已存在定义beanName
if (mbd == null && containsBeanDefinition(beanName)) {
//将存储XML配置文件的GernericBeanDefinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义的而不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
//调用FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法,实现FactoryBean生产Bean对象实例的过程
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
逻辑分析:
(1) 对FactoryBean正确性的验证
(2) 对非FactoryBean不做任何处理,直接返回bean
(3) 对bean进行转换
(4) 将从Factory中解析bean的工作委托给geiObjectFromFactoryBean
getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) 方法的实现:
//public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// Bean工厂是单态模式,并且Bean工厂缓存中存在指定名称的Bean实例对象
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 直接从Bean工厂缓存中获取指定名称的Bean实例对象
Object object = this.factoryBeanObjectCache.get(beanName);
// Bean工厂缓存中没有指定名称的实例对象,则生产该实例对象
if (object == null) {
// 调用Bean工厂的getObject方法生产指定Bean的实例对象
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}else {
if (object != null && shouldPostProcess) {
try {
//为创建出来的Bean实例对象添加BeanPostProcessor后置处理器
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,"Post-processing of FactoryBean's singleton object failed", ex);
}
}
//将生产的实例对象添加到Bean工厂缓存
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
//bean工厂不是单例的
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName) throws BeanCreationException {
Object object;
try {
//需要权限验证
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
//实现PrivilegedExceptionAction接口的匿名内置类
//根据JVM检查权限,然后决定BeanFactory创建实例对象
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
//调用BeanFactory接口实现类的创建对象方法
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//调用BeanFactory接口实现类的创建对象方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
//创建出来的实例对象为null,或者因为单态对象正在创建而返回null
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
//public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
return applyBeanPostProcessorsAfterInitialization(object, beanName);
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
逻辑分析:
(1) 在getObjectFromFactoryBean方法中首先判断factory是否是单例的, 如果是单例的,则尝试从缓存中获取bean实例对象, 获取不到的话再调用doGetObjectFromFactoryBean生产该实例对象, 然后将生产的实例对象添加到Bean工厂缓存; 如果factory不是单例的,则直接调用doGetObjectFromFactoryBean生产该实例对象并返回;
(2) 在doGetObjectFromFactoryBean方法中调用FactoryBean中对应的getObject()方法创建并返回bean实例
(3) spring在获取bean的规则中有这样一条: 尽可能保证所有bean初始化后都会调用注册的BeanPostProcessor的postProcessAfterInitialization方法进行处理,在实际开发中大可以针对此特性设计自己的业务逻辑
4、创建单例bean
如果从缓存中没有获取到单例bean,那么会先进行以下步骤为创建bean做准备:
- 原型模式的依赖检查, 只有在单例情况下才会尝试解决循环依赖; 如果是原型模式, 则抛出异常
- 检测parentBeanFactory
- 将存储XML配置文件的GerenicBeanDefinition转换为RootBeanDefintion, 转换的同时如果父类bean不为空的话,则会合并父类的属性
- 保证当前bean所依赖的bean的初始化, 通过dependsOn属性获取到将要创建的bean所依赖的bean, 对依赖的bean进行实例化
接下来就可以根据scope的不同来创建bean
. . .
// 单例模式的创建 (通过匿名内部类进行创建)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
. . .
getSingleton(String beanName, ObjectFactory<?> singletonFactory) 方法的实现:
//public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
//全局变量需要同步
synchronized (this.singletonObjects) {
//首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用已创建的bean,所以这一步是必须的
Object singletonObject = this.singletonObjects.get(beanName);
//如果为空,才进行singleton的bean初始化
if (singletonObject == null) {
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 + "'");
}
//加载单例前 记录加载状态: 将beanName放入singletonsCurrentlyInCreation属性中,并且从创建检查中排除的bean的名称
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<Exception>();
}
try {
//初始化bean(通过调用参数传入的ObjectFactory的getObject()方法实例化bean)
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;
}
//加载单例后的处理方法调用
afterSingletonCreation(beanName);
}
if (newSingleton) {
//将结果记录至缓存,并删除加载bean过程中所记录的各种状态
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
逻辑分析:
(1) 检查缓存是否已经加载过
(2) 若没有加载, 则记录beanName的正在加载状态
(3) 加载单例前记录加载状态, 通过this.singletonsCurrentlyInCreation.add(beanName)将当前正要创建的bean记录在缓存中, 这样便可以对循环依赖进行检测
(4) 通过调用参数传入的ObjectFactory的个体Object方法实例化bean; 即调用匿名内部类中的createBean(beanName, mbd, args)方法创建bean
(5) 加载单例后的处理方法调用, 当bean加载完成后需要移除缓存中对该bean的正在加载状态的记录
(6) 将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态
(7) 返回处理结果
5、准备创建bean
createBean(beanName, mbd, args)
createBean(String beanName, RootBeanDefinition mbd, Object[] args)方法的实现:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
//1.锁定class,根据class属性或者根据className来解析Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证及准备覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 给BeanPostProcessors一个机会来返回代理,并用代理替代真正的实例
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
// 创建bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
逻辑分析:
(1) 根据设置的class属性或者根据className来解析Class
(2) 对override属性进行标记及验证, 在spring配置中有lookup-method和replace-method的, 而这两个属性的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里, 而这个函数的操作其实也就是针对于这两个配置的
(3) 应用初始化前的后处理器, 解析指定bean是否存在初始化前的短路操作
(4) 创建bean
5.1 处理override属性
mbdToUse.prepareMethodOverrides()
//public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor implements BeanDefinition, Cloneable
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
MethodOverrides methodOverrides = getMethodOverrides();
if (!methodOverrides.isEmpty()) {
for (MethodOverride mo : methodOverrides.getOverrides()) {
prepareMethodOverride(mo);
}
}
}
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
//获取对应类中对应方法名的个数
int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
if (count == 0) {
throw new BeanDefinitionValidationException(
"Invalid method override: no method with name '" + mo.getMethodName() +
"' on class [" + getBeanClassName() + "]");
}
else if (count == 1) {
//标记MethodOverride暂未被覆盖,避免参数类型检查的开销
mo.setOverloaded(false);
}
}
逻辑分析:
(1) 在spring配置中有lookup-method和replace-method的, 而这两个属性的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里; 这两个配置的功能实现原理其实是在bean实例化的时候如果检测到存在methodOverrides属性, 会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理;
(2) 对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么,在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数; 但是, spring将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到的方法么不需要进行方法的参数匹配验证了, 而且还可以提前对方法存在性进行验证
5.2 实例化的前置处理
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
当经过前置处理器后返回的结果如果不为空,那么会直接略过后续的bean的创建而直接返回结果
resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) 方法的实现:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 确保此时实际解析了bean类
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//实例化前的后处理器应用
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
//实例化后的后处理器应用
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName)
throws BeansException {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
result = beanProcessor.postProcessAfterInitialization(result, beanName);
if (result == null) {
return result;
}
}
return result;
}
逻辑分析:
(1) 实例化前的后处理器应用
bean的实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前的处理,给子类一个修改BeanDefinition的机会, 也就是说当程序经过这个方法后, bean可能已经不是我们认为的bean了, 或许成为一个经过处理的代理bean,可能是通过CGLIB生成的,也可能是通过其他技术生成的
(2) 实例化后的后处理器应用
spring中的规则是在bean的初始化后尽可能保证将注册后处理器的beanPostProcessorsAfterInitialization方法应用到该bean中,因为如果返回的bean不为空,那么, 便不会再次经历普通bean的创建过程, 所以只能在这里应用后处理器的postProcessAfterInitialization方法