对于加载bean的功能,在Spring中的调用方法为:
MyTestBean bean = (MyTestBean)bf.getBean("myTestBean");
这句代码实现了什么样的功能呢?
来看看AbstractBeanFactory里咋写的
getBean
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//提取对应的beanName
String beanName = transformedBeanName(name);
Object bean;
/**
* 检查缓存中或者实例工厂中是否有对应的实例
* 为什么首先会使用这段代码呢
* 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,
* String创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提前曝光
* 也就是将ObjectFactory加入到缓存中,一旦下个bean创建时候需要依赖上个bean则直接使用ObjectFactory
*/
//直接尝试从缓存获取或者singletonFactories中的ObjectFactory中获取
// Eagerly check singleton cache for manually registered singletons.
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 + "'");
}
}
//返回对应的实例,有时候存在诸如BeanFactory的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
//只有在单例情况才会尝试解决循环依赖,原型模式情况下,如果存在
//A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为
//对于B的创建再次返回创建A,造成循环依赖,也就是下面的情况
//isPrototypeCurrentlyInCreation(beanName)为true
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果beanDefinitionMap中也就是在所有已经加载的类中不包括beanName则尝试从parentBeanFactory中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else 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);
}
}
//如果不是仅仅做类型检测则是创建bean,这里要进行记录
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
//将存储XML配置文件的GenericBeanDefinitino转换为RootBeanDefinition
//如果指定BeanName是子Bean的话会合并父类的相关属性
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
//若存在依赖则需要递归实例化依赖的bean
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//缓存依赖调用
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//实例化依赖的bean后便可以实例化mbd本身了
//singleton模式的创建
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
//prototype模式的创建(new)
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
//指定的scope上实例化bean
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
}
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, () -> {
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;
}
}
//检查需要的类型是否符合bean的实例类型
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
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;
}
仅从代码量就可看出bean的加载相当复杂,阅读这个方法后粗略地了解整个Spring加载bean的过程,对于加载过程中所涉及的步骤大致如下:
(1)转换对应beanName
String beanName = transformedBeanName(name);这里传入的参数name不一定就是beanName也可能是别名,也可能是FactoryBean,需要进行一系列的解析,这些解析内容包括如下内容。
- 去除FactoryBean的修饰符,也就是如果name="&aa",那么会首先去除&而使name=“aa”。
- 取指定alias所表示的最终beanName,例如别名A指向名称为B的bean则返回B;若别名A指向别名B,别名B又指向名称为C的bean则返回C
(2)尝试从缓存中加载单例
单例在Spring的同一个容器内只会被创建一次,后续再获取bean就直接从单例缓存中获取了。当然这里也只是尝试加载,首先尝试从缓存中加载,如果加载不成功则再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,在Spring中创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时候需要依赖上一个bean则直接使用ObjectFactory
(3)bean的实例化
如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。这里有必要强调一下,缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean。举个例子,假如我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance就是完成这个工作的。
(4)原型模式的依赖检查
只有在单例情况下才会尝试解决循环依赖,如果存在A中有B的属性,B中有A的属性,那么当依赖注入的时候,就会产生当A还未创建完的时候因为对于B的创建再次返回创建A,造成循环依赖,也就是情况:isPrototypeCurrentlyInCreation(beanName)判断true。
(5)检测parentBeanFactory
!containsBeanDefinition(beanName),它是在检测如果当前加载的XML配置文件中不包含beanName所对应的配置,就只能到parentBeanFactory去尝试下了,然后再去递归的调用getBean方法。
(6)将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition。
因为从XML配置文件中读取到的Bean信息是存储在GenericBeanDefinition中的,但是所有的Bean后续处理都是针对于RootBeanDefinition的,所以这里需要进行一个转换,转换的同时如果父类bean不为空的话,则会一并合并父类的属性。
(7)寻找依赖。
因为bean的初始化过程中很有可能会用到某些属性,而某些属性很可能是动态配置的,并且配置成依赖于其它的bean,那么这个时候就有必要先加载依赖的bean,所以,在Spring的加载顺序中,在初始化某一个bean的时候首先会初始化这个bean所对应的依赖。
(8)针对不同的scope进行bean的创建。
在Spring中存在着不同的scope,其中默认的是singleton,但是还有些其他的配置诸如prototype、request之类的。在这个步骤中,Spring会根据不同的配置进行不同的初始化策略。
(9)类型转换
通常对该方法的调用参数requiredType是为空的,但是可能会存在这样的情况,返回的bean其实是个String,但是requiredType却传入Integer类型,那么这时候本步骤就会起作用了,它的功能是将返回的bean转换为requiredType所指定的类型。当然,String转换为Integer是最简单的一种转换,在Spring中提供了各种各样的转换器,用户也可以自己扩展转换器来满足需求。
在细化分析各种步骤提供的功能前,先了解下FactoryBean的用法。
FactoryBean的使用
实例化bean的过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。
从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式:
public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
当配置文件中的class属性配置的实现类是FactoryBean时,通过getBean()方法返回的不是FactoryBean本身,而是FactoryBean的getObject()方法所返回的对象,相当于FactoryBean的getObject()代理了getBean()方法。
例如:如果使用传统方式配置下面Car的时,Car的每个属性分别对应一个元素标签。
public class Car{
private Integer maxSpeed;
private String brand;
private Double price;
//get/set
}
如果用FactoryBean的方式实现就会灵活一些,下例通过逗号分割符的方式一次性地为Car的所有属性指定配置值:
public class CarFactoryBean implements FactoryBean<Car>{
private String carInfo;
public Car getObject() throws Exception{
Car car = new Car();
car.set(xxxxx);
...
...
return car;
}
public Class<Car> getObjectType(){return Car.class;}
public boolean isSingleton(){return false;}
public String getCarInfo(){return this.carInfo;}
public void setCarInfo(String carInfo){this.carInfo=carInfo;}
}
有了这个CarFactoryBean后,就可以在配置文件中使用下面这种自定义的配置方式配置CarBean 了:
<bean id="car" class="com.test.factorybean.CarFactoryBean" carInfo="xx,xx,xx" />
当调用getBean(“car”)时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean的getObject()方法返回。如果希望获取CarFactoryBean的实例,则需要在使用getBean(beanName)方法时在beanName前显示的加上“&”前缀,例如getBean("&car")。
缓存中获取单例bean
单例在Spring的同一个容器内只会被创建一次,后续再获取bean直接从单例缓存中获取。首先尝试从缓存中加载,然后再次尝试从singletonFactories中加载。因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖上个bean,则直接使用ObjectFactory。
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//如果为空,则锁定全局变量并进行处理
synchronized (this.singletonObjects) {
//如果此bean正在加载则不处理
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
//当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//调用预先设定的getObject方法
singletonObject = singletonFactory.getObject();
//记录在缓存中,earlySingletonObjects和singletonFactories互斥
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
首先尝试从singletonObjects中获取实例,如果获取不到就再从earlySingletonObjects里面获取,如果还获取不到,再尝试从singletonFactories里面获取beanName对应的ObjectFactory,然后调用这个ObjectFactory的getObject来创建bean,并放到earlySingletonObjects里面去,并且从singletonFactories里面remove掉这个ObjectFactory,而对于后续的所有内存操作都只为了循环依赖检测时候使用,也就是在allowEarlyReference为true的情况下才会使用。
从bean的实例中获取对象
getObjectForBeanInstance是个高频率使用的方法,无论是从缓存中获得bean还是根据不同的scope策略加载bean。
用来检测当前bean是否是FactoryBean类型的bean,如果是,那么需要调用该bean对应的FactoryBean实例中的getObject作为返回值。
无论从缓存中获取到的bean还是通过不同的scope策略加载的bean都只是最原始的bean状态,并不一定是我们最终想要的bean。举个例子,假如我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态,但是我们真正需要的是工厂bean中定义的factory-method方法中返回的bean,而getObjectForBeanInstance方法就是完成这个工作的。
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
//如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型则验证不通过
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// 现在我们有了个bean的实例,这个实例可能会是正常的bean或者是FactoryBean
// 如果是FactoryBean我们使用它创建实例,但是如果用户想要直接获取工厂实例而不是工厂的
// getObject方法对应的实例那么传入的name应该加入前缀&
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
//加载FactoryBean
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配置文件的GenericBeanDefinition转换为RootBeanDefinition
//如果指定BeanName是子bean的话同时会合并父类的相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义的而不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
来看看做了什么
1.对FactoryBean正确性的验证
2.对非FactoryBean不做任何处理
3.对bean进行转换
4.将从Factory中解析bean的工作委托给getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
beforeSingletonCreation(beanName);
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
这段代码就是返回的bean如果是单例的,那就必须保证全局唯一,同时也因为是单例的,所以不必重复创建,可以使用缓存来提高性能,也就是说已经加载过就要记录下来以便于下次复用,否则的话就直接获取了。
再来看看doGetObjectFromFactoryBean方法
private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged((PrivilegedExceptionAction<Object>) factory::getObject, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//直接调用getObject方法
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
return object;
}
这里看到了直接调用了factory.getObject()方法,终于!
获取单例
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name 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 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<>();
}
try {
//初始化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) {
//加入缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
上述代码中其实是使用了回调方法,使得程序可以在单例创建的前后做一些准备及处理操作,而真正的获取单例bean的方法其实并不是在此方法中实现的,其实现逻辑是在ObjectFactory类型的实例singletonFactory中实现的。而这些准备及处理操作包括如下内容:
1、检查缓存是否已经加载过。
2、若没有加载,则记录beanName的正在加载状态
3、加载单例前记录加载状态。
来看上下beforeSingletonCreation方法,这并不是一个空实现的方法,他做了一个操作:记录加载状态
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
4、通过调用参数传入的ObjectFactory的个体Object方法实例化bean
5、加载单例后的处理方法调用
同步骤3,当bean加载结束后需要移除缓存中对该bean的正在加载状态的记录afterSingletonCreation(beanName);
6、将结果记录至缓存并删除加载bean过程中所记录的各种辅助状态。
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
7、返回处理结果
通过看getSingleton方法可以反推参数
sharedInstance = getSingleton(beanName, new ObjectFactory<Object> {
public Object getObject() throws BeansException{
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
ObjectFactory的核心部分其实只是调用了createBean的方法,所以还得看一看createBean方法
准备创建bean
看看createBean函数
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
//锁定class,根据设置的class属性或者根据className来解析class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
//验证及准备覆盖的方法
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
//给BeanPostProcessors一个机会来返回代理来替代真正的实例
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
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);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
1、根据设置的class属性或者根据className来解析Class
2、对override属性进行标记及验证
3、应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作。
4、创建bean
处理override属性
查看AbstractBeanDefinition类的prepareMethodOverrides方法
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exist and determine their overloaded status.
if (hasMethodOverrides()) {
getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
}
}
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暂未被覆盖,避免参数类型检查的开销
// Mark override as not overloaded, to avoid the overhead of arg type checking.
mo.setOverloaded(false);
}
}
在Spring配置中存在lookup-method和replace-method两个配置功能,而这两个配置的加载其实就是将配置统一存放在BeanDefinition中的methodOverrides属性里,这两个功能实现原理其实是在bean实例化的时候如果检测到存在methodOverrides属性,会动态地为当前bean生成代理并使用对应的拦截器为bean做增强处理,相关逻辑实在在bean的实例化部分再看。
实例化的前置处理
在真正调用doCreate方法创建bean的实例前有这两行代码
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
这里有一个判断,如果进行前置处理后结果不为空,那么会直接略过后续的Bean创建而直接返回结果。这一特性虽然很容易被忽略,但是却起着很重要的作用,AOP功能就是基于这里判断的。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
//如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
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;
}
这里有两个方法
applyBeanPostProcessorsBeforeInstantiation:对后处理器中的所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法的调用。
applyBeanPostProcessorsAfterInitialization:对BeanPostProcessor的postProcessAfterInitialization方法的调用。
- 实例化前的后处理器应用
bean的实例化前调用,也就是将AbstractBeanDefinition转换为BeanWrapper前的处理。给子类一个修改BeanDefinition的机会,也就是说当程序经过这个方法后,bean可能已经不是我们认为的bean了,而是或许成为了一个经过处理的代理bean,可能是通过cglib生成的,也可能是通过其它技术生成的。我们只需要知道,在bean的实例化前会调用后处理器的方法进行处理。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
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;
}
- 实例化后的后处理器应用
Spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的postProcessAfterInitialization方法应用到该bean中。因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
什么是循环依赖
循环依赖就是循环引用,就是两个或多个bean相互之间的持有对方。
循环依赖是无法解决的,除非有终结条件,否则就是死循环,最终导致内存溢出错误。
Spring如何解决循环依赖
Spring容器循环依赖包括构造器循环依赖和setter循环依赖
-
构造器循环依赖
通过构造器注入构成的循环依赖,此依赖是无法解决的,只能抛出BeanCurrentlyInCreationException异常表示循环依赖。
Spring容器将每一个正在创建的bean标识符放在一个“当前创建bean池”中,bean标识符在创建过程中将一直保持在这个池中,因此如果在创建bean过程中发现自己已经在“当前创建bean池”里时,将抛出BeanCurrentlyInCreationException异常表示循环依赖,而对于创建完毕的bean将从“当前创建bean池”中清除掉。 -
setter循环依赖
表示通过setter注入方式构成的循环依赖,对于setter注入造成的依赖是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤的bean来完成的,而且只能解决单例作用域的bean循环依赖。通过提前暴露一个单例工厂方法,从而便其它bean能引用到该bean。
创建bean
常规的bean的创建是在doCreateBean中完成的
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//如果是单例则需要首先清除缓存。
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
//将BeanDefinition转换为BeanWrapper
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//应用MergedBeanDefinitionPostProcessor
//bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
/**
* 是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
*/
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/**
* 为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
* 这里的箭头函数其实是返回了一个ObjectFactory对象并且重写了getObject方法
* 在getObject方法里返回了getEarlyBeanReference方法
* 对bean再一次依赖引用,主要应用SmartInstantiationAware BeanPostProcessor
* 其中我们熟知的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean
populateBean(beanName, mbd, instanceWrapper);
//调用初始化方法,比如init-method
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
//earlySingletonReference只有在检测到有循环依赖的情况下才不会为空
if (earlySingletonReference != null) {
//如果exposedObject没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
//检测依赖
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
/**
* 因为bean创建后其所依赖的bean一定是已经创建的
* actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在循环依赖
*/
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//根据scopes注册bean
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
1、如果是单例则需要首先清除缓存
2、实例化bean,将BeanDefinition转换为BeanWrapper
3、MergedBeanDefinitionPostProcessor的应用
4、依赖处理
5、属性填充。将所有属性填充至bean的实例中
6、循环依赖检查,解决循环依赖只有对单例有效,其它的得抛出异常
7、注册DisposableBean。如果配置了destroy-method,这里需要注册以便于在销毁时调用。
8、完成创建并返回
创建bean的实例
先从createBeanInstance开始
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//解析class
Class<?> beanClass = resolveBeanClass(mbd, beanName);
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
//如果工厂方法不为空则使用工厂方法初始化策略
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要根据参数锁定构造函数或对应的工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果已经解析过则使用解析好的构造函数方法不需要再次锁定
if (resolved) {
if (autowireNecessary) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认构造函数构造
return instantiateBean(beanName, mbd);
}
}
//需要根据参数解析构造函数
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, ctors, args);
}
//使用默认构造函数构造
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
1、如果在RootBeanDefinition中存在factoryMethodName属性,或者说在配置文件中配置了factory-method,那么Spring会尝试使用instantiateUsingFactoryMethod方法根据RootBeanDefinition中的配置生成bean的实例
2、解析构造函数并进行构造函数的实例化。因为一个bean对应的类中可能会有多个构造函数,而每个构造函数的参数不同,Spring在根据参数及类型去判断最终会使用哪个构造函数进行实例化。但是,判断的过程是个比较消耗性能的步骤,所以采用缓存机制,如果已经解析过则不需要重复解析而是直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值去取,否则需要再次解析,并将解析的结果添加至RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod中。
autowireConstructor方法
对于实例的创建Sping中分成了两种情况,一种是通用的实例化,另一种是带有参数的实例化。
public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//explicitArgs通过getBean方法传入
//如果getBean方法调用的时候指定方法参数直接使用
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
//如果在getBean方法时候没有指定则尝试从配置文件中解析
Object[] argsToResolve = null;
//尝试从缓存中获取
synchronized (mbd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// Found a cached constructor...
//从缓存中取
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
//配置的构造函数参数
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果缓存中存在
if (argsToResolve != null) {
//解析参数类型,如给定方法的构造函数A(int,int)则通过此方法把配置中的("1","1")变为(1,1)
//缓存中的值可能是原始值也可能是最终值
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//没有被缓存
if (constructorToUse == null) {
// Need to resolve the constructor.
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//提取配置文件中的配置的构造函数参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
//用于承载解析后的构造函数参数的值
resolvedValues = new ConstructorArgumentValues();
//能解析到的参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
// Take specified constructors, if any.
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
candidates = (mbd.isNonPublicAccessAllowed() ?
beanClass.getDeclaredConstructors() : beanClass.getConstructors());
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
}
//排序给定的构造函数,public构造函数优先参数数量降序、非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Constructor<?> candidate : candidates) {
Class<?>[] paramTypes = candidate.getParameterTypes();
if (constructorToUse != null && argsToUse.length > paramTypes.length) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
//如果已经找到选用的构造函数或者需要的参数个数小于当前的构造函数参数个数则终止,因为已经按照参数个数降序排列
break;
}
if (paramTypes.length < minNrOfArgs) {
//参数个数不相等
continue;
}
ArgumentsHolder argsHolder;
if (resolvedValues != null) {
//有参数则根据值构造对应参数类型的参数
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if (paramNames == null) {
//获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取指定构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
//根据名称和数据类型创建参数持有者
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
getUserDeclaredConstructor(candidate), autowiring);
}
catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
//构造函数没有参数的情况
argsHolder = new ArgumentsHolder(explicitArgs);
}
//探测是否有不确定性的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
//如果它代表着当前最接近的匹配则选择作为构造函数
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
if (ambiguousConstructors == null) {
ambiguousConstructors = new LinkedHashSet<>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
if (constructorToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Could not resolve matching constructor " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Ambiguous constructor matches found in bean '" + beanName + "' " +
"(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
ambiguousConstructors);
}
if (explicitArgs == null) {
//将解析的构造函数加入缓存
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
final InstantiationStrategy strategy = beanFactory.getInstantiationStrategy();
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
strategy.instantiate(mbd, beanName, beanFactory, ctorToUse, argumentsToUse),
beanFactory.getAccessControlContext());
}
else {
beanInstance = strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
//将构建的实例加入BeanWrapper中
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
这个方法太复杂了…
1、构造函数参数的确定
- 根据explicitArgs参数判断
这个方法传了一个参数 Object[] explicitArgs ,如果传入的参数不为空,那边可以直接确定参数,因为参数是在调用Bean的时候用户指定的,在BeanFactory类中存在这样的方法:
Object getBean(String name,Object... args)
在获取bean的时候,用户不但可以指定bean的名称还可以指定bean所对应类的构造函数或者工厂方法的方法参数,主要用于静态工厂的调用,而这里是需要给定完全匹配的参数的,所以,便可以判断,如果传入参数explicitArgs不为空,则可以确定构造函数参数就是它。
- 缓存中获取
如果构造函数参数已经记录在缓存中,那么便可以直接拿来使用。而且,这里要提到的是,在缓存中缓存的是可能是参数的最终类型也可能是参数的初始类型。比如要求的是int类型但是传来的却是String类型,那么即使在缓存中得到了参数,也需要经过类型转换器的过滤以确保参数类型与对应的构造函数参数类型完全对应
- 配置文件获取
如果不能从参数中获取,也无法从缓存中获取,那么只能开始新一轮分析。
分析从获取配置文件中配置的构造函数信息开始,spring中配置文件中的信息经过转换都会通过BeanDefinition实例承载,也就是参数mbd中包含,那么可以调用mbd.getConstructorArgumentValues()来获取配置的构造函数信息。有了配置中的信息便可以获取对应的参数值信息了,获取参数值的信息包括直接指定值,如:直接指定构造函数中某个值为原始类型String 类型,或者是一个对其他bean的引用,而这一处理委托给resolveConstructorArguments方法,并返回能解析到的参数的个数。
2、 构造函数的确定
确定构造函数:根据构造函数参数确定对应的构造函数,匹配方法就是根据参数个数匹配。为了可以在遍历的情况下迅速判断排在后面的构造函数参数个数是否符合条件,会对构造函数按照参数数量降序。
指定参数名称设定参数:得先确定构造函数中的参数名称,获取参数名称有两种方式,一种是通过注解,另一种就是使用Spring中提供的工具类ParameterNameDiscoverer来获取。
3、根据确定的构造函数转换对应的参数类型
主要使用Spring中提供的类型转换器或者用户提供的自定义类型转换器进行转换。
4、构造函数不确定性的验证
有时候即使构造函数、参数名称、参数类型、参数值都确定后也不一定会直接锁定构造函数,不同构造函数的参数为父子关系,所以spring在最后又做了一次验证。
5、根据实例化策略以及得到的构造函数及构造函数参数实例化Bean。
instantiateBean
有参数的构造函数的实例构造非常复杂,不带参数的就很好理解
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
try {
Object beanInstance;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(
(PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
getAccessControlContext());
}
else {
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
直接调用实例化策略进行实例化…
实例化策略
这里的实例化策略就是instantiate方法了,来看看这个方法
SimpleInstantiationStrategy.java
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
CglibSubclassingInstantiationStrategy
public Object instantiate(@Nullable Constructor<?> ctor, @Nullable Object... args) {
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
/**
* Create an enhanced subclass of the bean class for the provided bean
* definition, using CGLIB.
*/
private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(beanDefinition.getBeanClass());
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
if (this.owner instanceof ConfigurableBeanFactory) {
ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
}
enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
enhancer.setCallbackTypes(CALLBACK_TYPES);
return enhancer.createClass();
}
首先判断有没有replace或者lookup的配置方法,如果没有直接使用反射,如果使用了这两个特性,需要将这两个配置提供的功能切入进去,所以就必须使用动态代理的方式将包含两个特性所对应的逻辑的拦截增强器设置进去,这样才可以保证在调用方法的时候会被相应的拦截器增强,返回值为包含拦截器的代理实例。
记录创建bean的ObjectFactory
/**
* 是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖
*/
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
/**
* 为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂
* 这里的箭头函数其实是返回了一个ObjectFactory对象并且重写了getObject方法
* 在getObject方法里返回了getEarlyBeanReference方法
* 对bean再一次依赖引用,主要应用SmartInstantiationAware BeanPostProcessor
* 其中我们熟知的AOP就是在这里将advice动态织入bean中,若没有则直接返回bean,不做任何处理
*/
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
先说一下循环依赖,创建A的时候会将A的创建工厂加入缓存中,而在对A的属性填充时会对B进行递归创建。同样,在B中同样存在A,因此在实例化B的时候又会再次创建A。这里不会直接去实例化A,而是先去检测缓存中是否有已经创建好的对应的bean,或者是否已经创建好的ObjectFactory,而此时对于A的ObjectFactory我们早已经创建,所以便不会再去向后执行,而是直接调用ObjectFactory去创建A。
看看getEarlyBeanReference的代码
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
这里就是调用了后处理器。
理一下,在B中创建依赖A时通过ObjectFactory提供的实例化方法来中断A中的属性填充,使B中持有的A仅仅是刚刚初始化并没有填充任何属性的A,而这正初始化A的步骤还是在最开始创建A的时候进行的,但是因为A与B中的A所表示的属性地址是一样的,所以在A中创建好的属性填充自然可以通过B中的A获取,这样就解决了循环依赖的问题。
属性注入
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
//没有可填充的属性
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//返回值为是否继续填充bean
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
//resolvedAutowireMode:自动注入模型,默认为AUTOWIRE_CONSTRUCTOR,所以这里不会进if,
// 如果该BeanDefinition的注入模型是这两种的,那么则分别的可以尝试byType方式,byName方式。
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
//后处理器已经初始化
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//需要依赖检查
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//对所有需要依赖检查的属性进行后处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
if (needsDepCheck) {
//依赖检查
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
if (pvs != null) {
//将属性应用到bean中
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
1、InstantiationAwareBeanPostProcessor处理器的postProcessAfterInstantiation方法用来判断是否继续进行属性填充。
2、根据注入类型(byName/byType),提取依赖的bean,并统一存入PropertyValues中。
3、应用InstantiationAwareBeanPostProcessor处理器的postProcessPropertyValues方法,对属性获取完毕填充前对属性的再次处理
4、将所有PropertyValues中的属性填充至BeanWrapper中。
autowireByName
protected void autowireByName(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//寻找bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
if (containsBean(propertyName)) {
//递归初始化相关的bean
Object bean = getBean(propertyName);
pvs.add(propertyName, bean);
//注册依赖
registerDependentBean(propertyName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Added autowiring by name from bean name '" + beanName +
"' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
"' by name: no matching bean found");
}
}
}
}
在传入的参数pvs中找出已经加载的bean,并递归实例化,进而加入到pvs中
autowireByType
protected void autowireByType(
String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
//寻找bw中需要依赖注入的属性
String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
for (String propertyName : propertyNames) {
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
// Don't try autowiring by type for type Object: never makes sense,
// even if it technically is a unsatisfied, non-simple property.
if (Object.class != pd.getPropertyType()) {
//探测指定属性的set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
// Do not allow eager init for type matching in case of a prioritized post-processor.
boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
//解析指定beanName的属性所匹配的值,并把解析到的属性名称存储在autowiredBeanNames中,当属性存在多个封装bean时如:
//@Autowired private List<A> aList; 会找到所有匹配A类型的bean并将其注入
Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
if (autowiredArgument != null) {
pvs.add(propertyName, autowiredArgument);
}
for (String autowiredBeanName : autowiredBeanNames) {
//注册依赖
registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +
propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
}
}
}
实现根据名称自动匹配的第一步就是寻找bw中需要依赖注入的属性,同样对于根据类型自动匹配的实现来讲第一步也是寻找bw中需要依赖注入的属性,然后遍历这些属性并寻找类型匹配的bean,其中最复杂的就是寻找类型匹配的bean。同时,Spring中提供了对集合的类型注入的支持,如使用注解的方式:
@Autowired
private List<Test> tests;
Spring将会把所有与Test匹配的类型找出来并注入到test属性中,正由于这一因素,所以在autowireByType函数中,新建了局部遍历autowiredBeanNames,用于存储所有依赖的bean,如果只是对非集合类的属性注入来说,此属性并无用处。
对于寻找类型匹配的逻辑实现封装在了resolveDependency函数中
public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
try {
Object shortcut = descriptor.resolveShortcut(this);
if (shortcut != null) {
return shortcut;
}
//获取需要注入的属性的类型(需要注入的属性的相关信息是封装在了DependencyDescriptor中)
Class<?> type = descriptor.getDependencyType();
//用于支持Spring中新增的注解@Value
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
//如果value值不为空,则TypeConverter将value转换成相应类型后,直接返回
if (value != null) {
if (value instanceof String) {
String strVal = resolveEmbeddedValue((String) value);
BeanDefinition bd = (beanName != null && containsBean(beanName) ? getMergedBeanDefinition(beanName) : null);
value = evaluateBeanDefinitionString(strVal, bd);
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
return (descriptor.getField() != null ?
converter.convertIfNecessary(value, type, descriptor.getField()) :
converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
}
//如果需要注入的属性是数组或者List等类型的处理
Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
if (multipleBeans != null) {
return multipleBeans;
}
//如果不是数组等类型,就找出所有满足要求的bean,再进行进一步的处理
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
if (matchingBeans.isEmpty()) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
return null;
}
String autowiredBeanName;
Object instanceCandidate;
//当有多个bean匹配类型的情况
if (matchingBeans.size() > 1) {
autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
if (autowiredBeanName == null) {
if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
return descriptor.resolveNotUnique(type, matchingBeans);
}
else {
// In case of an optional Collection/Map, silently ignore a non-unique case:
// possibly it was meant to be an empty collection of multiple regular beans
// (before 4.3 in particular when we didn't even look for collection beans).
return null;
}
}
instanceCandidate = matchingBeans.get(autowiredBeanName);
}
else {
//只有唯一的bean类型匹配,就返回这个bean
// We have exactly one match.
Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
autowiredBeanName = entry.getKey();
instanceCandidate = entry.getValue();
}
if (autowiredBeanNames != null) {
autowiredBeanNames.add(autowiredBeanName);
}
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
if (result instanceof NullBean) {
if (isRequired(descriptor)) {
raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
}
result = null;
}
if (!ClassUtils.isAssignableValue(type, result)) {
throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
}
return result;
}
finally {
ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
}
}
从上面的代码可以看出,spring对注入情况分为3类:
1、如果存在@Value注解,就直接解析注解的value值,然后通过类型转换器进行类型转换后就得到了想要的值;
2、如果需要注入的数组、List等类型,就找出类型匹配的beans返回;
3、如果是一个非数组类型,找到所有匹配的beans后还需要进行一些判断;
处理数组类型resolveMultipleBeans方法
//数组类型的处理
private Object resolveMultipleBeans(DependencyDescriptor descriptor, String beanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) {
Class<?> type = descriptor.getDependencyType();
//对于数组、Collection、Map,spring是分开处理的,但是大致逻辑都十分详细
//可以看到不管是那种类型,对bean的搜寻都是放在了findAutowireCandidates函数中
if (type.isArray()) {
Class<?> componentType = type.getComponentType();
ResolvableType resolvableType = descriptor.getResolvableType();
Class<?> resolvedArrayType = resolvableType.resolve();
if (resolvedArrayType != null && resolvedArrayType != type) {
type = resolvedArrayType;
componentType = resolvableType.getComponentType().resolve();
}
if (componentType == null) {
return null;
}
//根据属性类型找到beanFactory中所有类型的匹配bean,
//返回值的构成为:key=匹配的beanName,value=beanName对应的实例化后的bean
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (getDependencyComparator() != null && result instanceof Object[]) {
Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
}
return result;
}
else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
Class<?> elementType = descriptor.getResolvableType().asCollection().resolveGeneric();
if (elementType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, elementType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
if (getDependencyComparator() != null && result instanceof List) {
Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
}
return result;
}
else if (Map.class == type) {
ResolvableType mapType = descriptor.getResolvableType().asMap();
Class<?> keyType = mapType.resolveGeneric(0);
if (String.class != keyType) {
return null;
}
Class<?> valueType = mapType.resolveGeneric(1);
if (valueType == null) {
return null;
}
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
new MultiElementDescriptor(descriptor));
if (matchingBeans.isEmpty()) {
return null;
}
if (autowiredBeanNames != null) {
autowiredBeanNames.addAll(matchingBeans.keySet());
}
return matchingBeans;
}
else {
return null;
}
}
由于是分类进行处理的,所以上面的代码比较长,但是对bean的搜寻都是放在了findAutowireCandidates函数中。并且如果仔细看的话,其实对非数组类型而言,对bean的搜寻也是在该函数中,只是入参稍有不同:
//数组类型
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, componentType,
new MultiElementDescriptor(descriptor));
//非数组类型
Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
findAutowireCandidates
protected Map<String, Object> findAutowireCandidates(
String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
//获取候选bean的beanName列表
String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = new LinkedHashMap<String, Object>(candidateNames.length);
for (Class<?> autowiringType : this.resolvableDependencies.keySet()) {
if (autowiringType.isAssignableFrom(requiredType)) {
Object autowiringValue = this.resolvableDependencies.get(autowiringType);
autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
if (requiredType.isInstance(autowiringValue)) {
result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
break;
}
}
}
//将匹配的beanName(保证beanName锁对应bean不是自身)和bean实例加入到result中
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
//...
return result;
}
applyPropertyValues
程序运行到这里,已经完成了对所有注入属性的获取,但是获取的属性是以PropertyValues形式存在的,还并没有应用到已经实例化的bean中
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
//如果mpvs中的值已经被转换为对应的类型那么可以直接设置到beanwapper中
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
//如果ps并不是使用MutablePropertyValues封装的类型,那么直接使用原始的属性获取方法
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
//获取对应的解析器
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
//遍历属性,将属性转换为对应类的对应属性的类型
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue));
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
初始化bean
bean配置时bean中有一个init-method的属性,这个属性的作用是在bean实例化前调用init-mehtod指定的方法来根据用户业务进行相应的实例化。
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//对特殊的bean处理:Aware、BeanClassLoaderAware、BeanFactoryAware
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//应用后处理器
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
//激活用户自定义的init方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//后处理器应用
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
激活Aware方法
Spring中提供一些Aware相关接口,比如BeanFactoryAware、ApplicationContextAware、ResourceLoaderAware、ServletContextAware等,实现这些Aware接口的bean在被初始之后,可以取得一些相对应的资源,例如实现BeanFactoryAware的bean在初始后,Spring容器将会注入BeanFactory的实例,而实现ApplicationContextAware的bean,在bean被初始后,将会被注入ApplicationContext的实例等。
先来了解一下Aware的使用
(1)定义普通bean
public class Hello{
public void say(){
System.out.println("hello");
}
}
(2)定义BeanFactoryAware类型的bean
class Test implements BeanFactoryAware{
private BeanFactory beanFactory;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException{
this.beanFactory=beanFactory;
}
public void testAware(){
//通过hello这个bean id从beanFactory获取实例
Hello hello =(Hello) beanFactory.getBean("hello");
hello.say();
}
}
(3)使用main方法测试
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathAplicationContext("applicationContext.xml");
Test test = (Test) ctx.getBean("test");
test.testAware();
}
控制台输出:hello
按照上面的方法可以获取到Spring中BeanFactory,并且可以根据BeanFactory获取所有bean,以及进行相关设置。当然还有其他Aware的使用方法都差不多,看一下Spring的实现方式。
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
没啥好说的,很简单
处理器的应用
BeanPostProcessor给用户充足的权限去更改或者扩展Spring,而出了BeanPostProcessor还有很多PostProcessor,当然大部分都是以此为基础,继承自BeanPostProcessor。BeanPostProcessor的使用位置就是这里,在调用客户自定义初始化方法前以及调用自定义初始化方法后分别会调用BeanPostProcessor的postProcessBeforeInitialization和postProcessAfterInitialization方法,使用户可以根据业务需求进行响应的处理
激活自定义的init方法
定制的初始化方法除了我们熟知的init-method外,还有使自定义的bean实现InitializingBean接口,并在afterPropertiesSet中实现自己的初始化业务逻辑。
init-method与afterPropertiesSet都是在初始化bean时执行,执行顺序是afterPropertiesSet->init-method
在invokeInitMethods方法中就实现了这两个步骤的初始化方法调用
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//检测是不是initializingbean,如果是的话需要调用afterPropertiesSet
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
//调用自定义初始化方法
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
注册DisposableBean
对于销毁方法的扩展,除了destroy-method方法外,用户还可以注册后处理器DestructionAwareBeanPostProcessor来统一处理bean的销毁方法
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()) {
/**
* 单例模式下注册需要销毁的bean,此方法中会处理实现DisposableBean的bean,
* 并且对所有的bean使用DestructionAwareBeanPostProcessors处理
*/
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
//自定义scope的处理
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}