在聊bean加载之前,我们先聊一下FactoryBean的使用。我们一般在spring配置文件时,spring通过反射机制来实例化我们制定的class,可是我们需要在bean中配置大量的信息,那么FactoryBean就诞生了,我们通过实现FactoryBean的接口,我们自己编码来生成这个需要的实例。
FactoryBean的使用
①先创造出一个我们需要生成的类
public class User {
private String userName;
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
③实现我们自己的FactoryBean
public class UserFactoryBean implements FactoryBean<User>{
private String infors;
public User getObject() throws Exception {
User user = new User;
String[] s = infors.split(",");
user.setUserName(s[0]);
user.setEmail(s[1]);
return user;
}
public Class<?> getObjectType() {
return User.class;
}
public boolean isSingleton() {
return false;
}
public void setInfors(String infors) {
this.infors = infors;
}
}
③配置spring.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="user" class="factorybean.UserFactoryBean">
<property name="infors" value="whz,54524@qq.com"></property>
</bean>
</beans>
④测试
@Test
public void testSimpleLoad(){
BeanFactory bf =new XmlBeanFactory(new ClassPathResource(("beanFactoryTest.xml")));
User myTestBean = (User)bf.getBean("user");
System.out.println(myTestBean.getEmail());
}
结果:
54524@qq.com
FactoryBean小结
当我们调用getBean(“user”),spring通过反射机制发现该类实现了接口FactoryBean,则会调用接口方法getObject来返回User实例,如果我想要获取正真的FactoryBean实现类,需要在user前面加个&,即”&user”.
Bean的加载
找到getBean方法
public Object getBean(String name) throws BeansException {
return this.doGetBean(name, (Class)null, (Object[])null, false);
}
继续进入,我们来一点一点分析代码
protected <T> T doGetBean(String name, Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
//把name转换为beanName,我们知道beanName是bean的唯一标识,那么这个name可以是beanName,也可能是别名,而且如果是FactoryBean就需要去掉&所以需要进行转换
final String beanName = this.transformedBeanName(name);
//从单例缓存中,或者从单例工厂中获取
Object sharedInstance = this.getSingleton(beanName);
进入这个方法,如果光看这个方法,可能会感觉有点乱,就算看懂了逻辑,也会难以理解其中一些对象的作用。那么我们先来说一下循环依赖这个问题。
有这么两个类:他们互相依赖
public class Chicken {
private Egg egg;
public Chicken(){
egg = new Egg();
}
}
public class Egg {
private Chicken chicken;
public Egg(){
chicken = new Chicken();
}
}
开始测试
@Test
public void relyTest(){
Chicken c = new Chicken();
}
结果:
java.lang.StackOverflowError
at bean.Egg.<init>(Egg.java:8)
at bean.Chicken.<init>(Chicken.java:9)
at bean.Egg.<init>(Egg.java:9)
堆栈溢出
因为Chicken类在实例化时需要实例化Egg类,而Egg类又要实例化一个Chicken类,这样循环的依赖最后导致了堆栈溢出。Spring中提出了一个解决循环依赖的方法,但是这方法解决的是单例之间的循环依赖,而且是单例中setter循环依赖的,构造方法中的依赖没有解决。总而言之,多例的循环依赖spring没有解决,因为多例的对象依赖是依赖一个新的对象,这种对象内存中可以创建无数个,这种循环依赖本身就是逻辑上有问题,除非对象依赖创建自己的对象,对象在创建依赖时将this传给需要的依赖,但这个肯定已经超出了xml配置的范畴。单例的循环依赖比较好处理,因为单例在内存中只有一份,bean的加载时分好多步骤的,比如bean的构造,一些属性的注入等等,spring首先会根据无参构造创建一个bean对象,然后将可以获取这个对象的ObjectFactory暴露出来,并将标识放在”当前创建bean池中”,这样需要依赖这个对象的实例,从这个池中找到ObjectFactory,然后获取到bean,最后将这个对象注入进来,这样就解决了循环依赖,但是spring为啥没有完成单例构造期间依赖,只是完成了setter时的依赖,很明显,创建对象是才调用构造方法,我构造时需要依赖A,A构造时需要依赖我,我连构造都没完成,还没产生我这个对象,那么A怎么依赖我,所以没有解决。
说完这个,我们来看下面的代码,这样不会很难理解。这个方法是从单例缓存中或者刚才所说的ObjectFactory中获取单例bean。
public Object getSingleton(String beanName) {
return this.getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//从bean已经加载完的单例缓存中获取单例的实例
Object singletonObject = this.singletonObjects.get(beanName);
//如果没有,但是正在创造这个单例
if(singletonObject == null && this.isSingletonCurrentlyInCreation(beanName)) {
Map var4 = this.singletonObjects;
synchronized(this.singletonObjects) {
//从正在创建的单例对象中获取
singletonObject = this.earlySingletonObjects.get(beanName);
//如果没有取到,而且允许早期引用,也就是说可以提前暴露
if(singletonObject == null && allowEarlyReference) {
//找到对应的单例工厂,之前我们说过,当单例bean构造完成就会产生一个可以获取这个bean对象的工厂,并把这个工厂放到工厂集合中,这段代码我们会在后面看到
ObjectFactory<?> singletonFactory = (ObjectFactory)this.singletonFactories.get(beanName);
//如果找到了这个工厂
if(singletonFactory != null) {
//从工厂工获取到未加载完成的bean
singletonObject = singletonFactory.getObject();
//记录到earlySingletonObjects中 this.earlySingletonObjects.put(beanName, singletonObject);
//从工厂集合中移除这个工厂,因为这个工厂中能获取的bean对象已经加载到了earlySingletonObjects集合中
this.singletonFactories.remove(beanName);
}
}
}
}
//将获取到的对象返回
return singletonObject != NULL_OBJECT?singletonObject:null;
}
看到这,我们可以知道,如果能从缓存中获取到单例对象,要么这个单例已经完成加载创建,或者这个单例bean正在创建,接下来看下面代码,这时候已经拿到了sharedInstance 。
Object bean;
if(sharedInstance != null && args == null) {
//此处省略一大堆debug输出
//返回对应的实例,可是我们不是获取到实例了吗?为啥还要获取一次呢,这就跟FactoryBean有关,之前我们可以获取到的是FactoryBean,但我们需要FactoryBean产生的对象
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, (RootBeanDefinition)null);
进入这个方法,得到我们想要的bean
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
//如果是name是以"&"开头,说明要获取的是工厂,而实例不是工厂类,那么验证不通过,抛出异常
if(BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(this.transformedBeanName(name), beanInstance.getClass());
//如果是工厂类,但是不是以"&"开头,也就是它想获取工厂产生的实例
} else if(beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
Object object = null;
if(mbd == null) {
//从缓存中获取bean对象
object = this.getCachedObjectForFactoryBean(beanName);
}
//如果没有
if(object == null) {
FactoryBean<?> factory = (FactoryBean)beanInstance;
//容器中是否存在这个类
if(mbd == null && this.containsBeanDefinition(beanName)) {
//将存储xml配置文件的GernericBeanDefinition转换成RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父亲相关属性
mbd = this.getMergedLocalBeanDefinition(beanName);
}
//是否是用户定义的而不是应用程序本身定义的
boolean synthetic = mbd != null && mbd.isSynthetic();
//从工厂bean中获取对象
object = this.getObjectFromFactoryBean(factory, beanName, !synthetic);
}
//返回对象
return object;
} else {
return beanInstance;
}
}
我们进入这个getObjectFromFactoryBean看一下如何获取实例化对象的,
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
//如果是单例模式,说明这个工厂只能返回同一个对象
if(factory.isSingleton() && this.containsSingleton(beanName)) {
synchronized(this.getSingletonMutex()) {
//先从工厂产生的对象缓存中获取这个实例
Object object = this.factoryBeanObjectCache.get(beanName);
//如果没获取到
if(object == null) {
//通过这个工厂来获取实例对象
object = this.doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
//因为这个对象是单例的,所以我们把对象存入缓存中 this.factoryBeanObjectCache.put(beanName, object != null?object:NULL_OBJECT);
}
//返回对象
return object != NULL_OBJECT?object:null;
}
} else {
return this.doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess);
}
}
我们来看一下doGetObjectFromFactoryBean方法怎么获取的对象,
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, String beanName, boolean shouldPostProcess) throws BeanCreationException {
Object object;
try {
//进行权限认证
if(System.getSecurityManager() != null) {
AccessControlContext acc = this.getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
} catch (PrivilegedActionException var8) {
throw var8.getException();
}
} else {
//调用我们创建的factorybean的getObject方法,得到对象
object = factory.getObject();
}
} catch (FactoryBeanNotInitializedException var9) {
throw new BeanCurrentlyInCreationException(beanName, var9.toString());
} catch (Throwable var10) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", var10);
}
if(object == null && this.isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
} else {
if(object != null && shouldPostProcess) {
try {
//调用ObjectFactory的后处理器
object = this.postProcessObjectFromFactoryBean(object, beanName);
} catch (Throwable var7) {
throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", var7);
}
}
//返回对象
return object;
}
}
现在又回到了最初从缓存中获取实例之后的代码,如果没有获取到
} else {
//如果原型模式下,也就是多例,如果A依赖B,B依赖A,B需要A时发现A已经在“正在创建池”中了,那么就是出现了循环依赖,那么我们又想,可是在多线程的情况下,也许就会出现两个同样对象正在创建的过程呀,但是,我们走进isPrototypeCurrentlyInCreation方法能发现,这个正在创建池采用的是ThreadLocal,在这个容器里面,每个线程都有自己的副本,互不干涉,所以在自己线程的正在创建池中发现了这个对象,那肯定是出现了循环依赖,那么旧抛出异常 if(this.isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = this.getParentBeanFactory();
//如果beanDefinitonMap中也就是所有已经加载的类不包括beanName则尝试从parentBeanFactory中检测
if(parentBeanFactory != null && !this.containsBeanDefinition(beanName)) {
String nameToLookup = this.originalBeanName(name);
//递归到BeanFactory中寻找
if(args != null) {
return parentBeanFactory.getBean(nameToLookup, args);
}
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
//这里不是仅仅做类型检查则是创建bean,这里要进行记录,表示已经创建
if(!typeCheckOnly) {
this.markBeanAsCreated(beanName);
}
try {
//将存储XML配置文件的GernericBeanDefintion转换为RootBeanDefinition,如果beanname是子bean就会合并父类相关属性
final RootBeanDefinition mbd = this.getMergedLocalBeanDefinition(beanName);
this.checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
String[] var11;
//如果存在依赖则需要递归实例化依赖的bean
if(dependsOn != null) {
var11 = dependsOn;
int var12 = dependsOn.length;
for(int var13 = 0; var13 < var12; ++var13) {
String dependsOnBean = var11[var13];
if(this.isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException("Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'");
}
//缓存依赖调用 this.registerDependentBean(dependsOnBean, beanName);
this.getBean(dependsOnBean);
}
}
//如果是单例模式
if(mbd.isSingleton()) {
//获取这个单例对象
sharedInstance = this.getSingleton(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
try {
return AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
});
我们来看一下getSingleton这个方法,之前是从缓存中获取单例,这次是重新创造一个单例,并获取。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
Map var3 = this.singletonObjects;
synchronized(this.singletonObjects) {
//尝试从已加载完成的bean集合中获取,可是有人要问了:不是刚才从缓存中获取了一遍,没有获取到单例吗,怎么现在又要获取了,可是我们要知道,spring很多时候是运行在多线程环境下的,比如web项目,所以在这之前可能这个bean就已经被加载完成了
Object singletonObject = this.singletonObjects.get(beanName);
//如果为空才对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(this.logger.isDebugEnabled()) {
this.logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
}
//记录bean的加载
this.beforeSingletonCreation(beanName);
boolean recordSuppressedExceptions = this.suppressedExceptions == null;
if(recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
//获取单例对象
singletonObject = singletonFactory.getObject();
我们进入这个方法查看,这个singletonFactory是我们之前传递进来的,getObject方法经过了我们的重写,我们找到这个方法,
public Object getObject() throws BeansException {
try {
return
//创建实例 AbstractBeanFactory.this.createBean(beanName, mbd, args);
} catch (BeansException var2) {
AbstractBeanFactory.this.destroySingleton(beanName);
throw var2;
}
}
进入这个方法查看,这是个抽象方法,所以我们从子类中寻找,
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Creating instance of bean '" + beanName + "'");
}
//锁定class,根据设置的class属性或根据className来解析class
this.resolveBeanClass(mbd, beanName, new Class[0]);
try {
//验证及准备覆盖的方法
mbd.prepareMethodOverrides();
} catch (BeanDefinitionValidationException var5) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", var5);
}
我们进入这个prepareMethodOverrides方法查看
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
MethodOverrides methodOverrides = this.getMethodOverrides();
if(!methodOverrides.isEmpty()) {
//获取所有需要被覆盖的方法
Iterator var2 = methodOverrides.getOverrides().iterator();
while(var2.hasNext()) {
MethodOverride mo = (MethodOverride)var2.next();
//处理覆盖方法
this.prepareMethodOverride(mo);
}
}
}
进入这个方法prepareMethodOverride,这方法的作用是对重载方法进行预处理,如果该方法没有被抽在,那么后续调用时变可以直接使用找到的方法,不需要进行参数匹配。
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
//获取对应类中对应方法名的个数
int count = ClassUtils.getMethodCountForName(this.getBeanClass(), mo.getMethodName());
if(count == 0) {
throw new BeanDefinitionValidationException("Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + this.getBeanClassName() + "]");
} else {
//标记MethodOverride暂未被覆盖,避免参数类型的检查开销
if(count == 1) {
mo.setOverloaded(false);
}
}
}
返回之前的方法,
Object beanInstance;
try {
//在初始化之前来返回代理,来代替真正的实例
beanInstance = this.resolveBeforeInstantiation(beanName, mbd);
if(beanInstance != null) {
return beanInstance;
}
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", var6);
}
进入这个方法查看
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if(!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
if(mbd.hasBeanClass() && !mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
//实例化前后处理器应用
bean = this.applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
进入方法,我们知道如果方法被修改或者被增强,那是要应用动态代理生成代理类,那么这个方法就是生成代理类的过程。动态代理我们放到后面再解析。
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Iterator var3 = this.getBeanPostProcessors().iterator();
while(var3.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var3.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if(result != null) {
return result;
}
}
}
return null;
}
接下来就是进行实例化后的后处理器应用
if(bean != null) {
bean = this.applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
}
return bean;
}
如果没有返回代理类,也就是说没有什么方法需要被覆盖或者增强,那么就创建bean
beanInstance = this.doCreateBean(beanName, mbd, args);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
进入这个doCreateBean方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, Object[] args) {
BeanWrapper instanceWrapper = null;
if(mbd.isSingleton()) {
instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
}
//根据指定bean使用对应的策略创建新的实例
if(instanceWrapper == null) {
instanceWrapper = this.createBeanInstance(beanName, mbd, args);
}
进入该方法,创建bean实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
//解析class,获得Class对象
Class<?> beanClass = this.resolveBeanClass(mbd, beanName, new Class[0]);
if(beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
} else if(mbd.getFactoryMethodName() != null) {
//如果工厂方法不为空就采用工厂方法初始化,通过反射机制实例化工厂,通过工厂方法匹配来调用工厂方法生成对象。
return this.instantiateUsingFactoryMethod(beanName, mbd, args);
} else {
boolean resolved = false;
boolean autowireNecessary = false;
if(args == null) {
Object var7 = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
//一个类有多个构造函数,每个构造函数都有不同的参数,所以调用前需要根据参数锁定构造函数或者对应的工厂方法 if(mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//如果已经解析过则兽用解析好的构造方法不需要再次锁定
if(resolved) {
//采用构造函数自动注入或者使用默认构造函数构造
return autowireNecessary?this.autowireConstructor(beanName, mbd, (Constructor[])null, (Object[])null):this.instantiateBean(beanName, mbd);
} else {
//如果没有解析,那么我们需要根据参数来获得构造方法
Constructor<?>[] ctors = this.determineConstructorsFromBeanPostProcessors(beanClass, beanName);
//通过构造函数注入或者默认构造函数构造
return ctors == null && mbd.getResolvedAutowireMode() != 3 && !mbd.hasConstructorArgumentValues() && ObjectUtils.isEmpty(args)?this.instantiateBean(beanName, mbd):this.autowireConstructor(beanName, mbd, ctors, args);
}
}
}
可能看到你上面的代码,你可以回对autowireConstructor和instantiateBean方法不明白。不知道该上面时候用哪个方法。instantiateBean是采用该类默认的构造方法,如果没有参数,那么必然是调instantiateBean这个默认的构造方法,但是如果有参数,可能这个参数是getBean的时候传递进来的,可能是在xml配置文件中配置的构造参数,如果有参数的时候,就需要采用autowireConstructor方法。autowireConstructor还采用了缓存机制,解析构造函数是需要时间的,从缓存中提取对应的构造函数会更加快。
接下来来分析autowireConstructor构造函数自动注入,代码非常长,这个过程很复杂
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd, Constructor<?>[] chosenCtors, Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
final Constructor<?> constructorToUse = null;
ConstructorResolver.ArgumentsHolder argsHolderToUse = null;
final Object[] argsToUse = null;
//下面是参数的处理部分,如果getBean传入了参数,那么就直接使用,如果没有就从配置文件中解析
if(explicitArgs != null) {
argsToUse = explicitArgs;
} else {
//从配置文件中解析参数
Object[] argsToResolve = null;
Object var10 = mbd.constructorArgumentLock;
synchronized(mbd.constructorArgumentLock) {
//从构造方法缓存中提取构造方法
constructorToUse = (Constructor)mbd.resolvedConstructorOrFactoryMethod;
//如果有缓存的构造方法
if(constructorToUse != null && mbd.constructorArgumentsResolved) {
//从缓存中提取构造参数
argsToUse = mbd.resolvedConstructorArguments;
if(argsToUse == null) {
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//如果缓存中存在参数
if(argsToResolve != null) {
//解析参数类型
argsToUse = this.resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//如果构造方法没有被缓存
if(constructorToUse == null) {
boolean autowiring = chosenCtors != null || mbd.getResolvedAutowireMode() == 3;
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if(explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
} else {
//如果没有外部参数
//提取配置文件中的构造参数
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//能解析到的参数个数
minNrOfArgs = this.resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//获取所有的构造函数
Constructor<?>[] candidates = chosenCtors;
if(chosenCtors == null) {
Class beanClass = mbd.getBeanClass();
try {
candidates = mbd.isNonPublicAccessAllowed()?beanClass.getDeclaredConstructors():beanClass.getConstructors();
} catch (Throwable var24) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", var24);
}
}
//排序给定的构造函数,public构造函数有限参数数量降序,非public构造函数参数数量降序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = 2147483647;
Set<Constructor<?>> ambiguousConstructors = null;
List<Exception> causes = null;
开始
for(int i = 0; i < candidates.length; ++i) {
Constructor<?> candidate = candidates[i];
Class<?>[] paramTypes = candidate.getParameterTypes();
if(constructorToUse != null && argsToUse.length > paramTypes.length) {
//如果之前从缓存中拿到了构造函数就跳出循环,或者需要的参数小于当前构造函数的参数,因为是根据参数数量降序的
break;
}
//如果构造函数参数个数比解析到的参数大或等于
if(paramTypes.length >= minNrOfArgs) {
ConstructorResolver.ArgumentsHolder argsHolder;
if(resolvedValues != null) {
try {
//注释上获取参数名称
String[] paramNames = ConstructorResolver.ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
if(paramNames == null) {
//获取参数名称探索器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if(pnd != null) {
//获取指定构造函数的参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
//根据名称和数据类型创建参数持有者
argsHolder = this.createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring);
} catch (UnsatisfiedDependencyException var25) {
if(this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + var25);
}
if(i == candidates.length - 1 && constructorToUse == null) {
if(causes != null) {
Iterator var21 = causes.iterator();
while(var21.hasNext()) {
Exception cause = (Exception)var21.next();
this.beanFactory.onSuppressedException(cause);
}
}
throw var25;
}
if(causes == null) {
causes = new LinkedList();
}
causes.add(var25);
continue;
}
} else {
if(paramTypes.length != explicitArgs.length) {
continue;
}
//构造函数没有参数
argsHolder = new ConstructorResolver.ArgumentsHolder(explicitArgs);
}
//探测是否有不确定的构造函数存在,例如不同构造函数的参数为父子关系
int typeDiffWeight = mbd.isLenientConstructorResolution()?argsHolder.getTypeDifferenceWeight(paramTypes):argsHolder.getAssignabilityWeight(paramTypes);
//如果它代表当前最接近的匹配则选择作为构造函数
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) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Could not resolve matching constructor (hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
}
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) {
//将解析的构造函数存入缓存,因为这个构造是在xml配置的,如果下次创建实例还是一样的构造
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
try {
Object beanInstance;
if(System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return ConstructorResolver.this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, ConstructorResolver.this.beanFactory, constructorToUse, argsToUse);
}
}, this.beanFactory.getAccessControlContext());
} else {
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
//将构建的实例放入BeanWrapper中
bw.setWrappedInstance(beanInstance);
return bw;
} catch (Throwable var23) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var23);
}
}
接下来我们来看默认的构造方法创建实例
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
if(System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return AbstractAutowireCapableBeanFactory.this.getInstantiationStrategy().instantiate(mbd, beanName, AbstractAutowireCapableBeanFactory.this);
}
}, this.getAccessControlContext());
} else {
beanInstance = this.getInstantiationStrategy().instantiate(mbd, beanName, this);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
this.initBeanWrapper(bw);
return bw;
} catch (Throwable var6) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", var6);
}
}
我们进入这个instantiate方法,这叫实例化策略,只要实例化,就需要用到这个。
public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) {
//如果没有需要改动的方法,那么通过反射机制进行实例化
if(beanDefinition.getMethodOverrides().isEmpty()) {
Object var5 = beanDefinition.constructorArgumentLock;
Constructor constructorToUse;
synchronized(beanDefinition.constructorArgumentLock) {
constructorToUse = (Constructor)beanDefinition.resolvedConstructorOrFactoryMethod;
if(constructorToUse == null) {
final Class<?> clazz = beanDefinition.getBeanClass();
if(clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if(System.getSecurityManager() != null) {
constructorToUse = (Constructor)AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[])null);
}
});
} else {
constructorToUse = clazz.getDeclaredConstructor((Class[])null);
}
beanDefinition.resolvedConstructorOrFactoryMethod = constructorToUse;
} catch (Exception var9) {
throw new BeanInstantiationException(clazz, "No default constructor found", var9);
}
}
}
return BeanUtils.instantiateClass(constructorToUse, new Object[0]);
} else {
//否则动态代理
return this.instantiateWithMethodInjection(beanDefinition, beanName, owner);
}
}
到这里已经得到了刚刚创建的实例
final Object bean = instanceWrapper != null?instanceWrapper.getWrappedInstance():null;
Class<?> beanType = instanceWrapper != null?instanceWrapper.getWrappedClass():null;
Object var7 = mbd.postProcessingLock;
synchronized(mbd.postProcessingLock) {
if(!mbd.postProcessed) {
this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
//是否需要提前曝光:要满足以下条件,单例,允许循环依赖,当前bean正在创建
boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);
if(earlySingletonExposure) {
if(this.logger.isDebugEnabled()) {
this.logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
}
//为了避免后期循环依赖,将可以获取到刚初始化完成的bean的工厂放入工厂集合中
this.addSingletonFactory(beanName, new ObjectFactory<Object>() {
public Object getObject() throws BeansException {
return AbstractAutowireCapableBeanFactory.this.getEarlyBeanReference(beanName, mbd, bean);
}
});
}
Object exposedObject = bean;
try {
//完成bean的初始化后就需要对bean的属性进行填充了
this.populateBean(beanName, mbd, instanceWrapper);
进入这个方法查看,这是bean属性的填充
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
PropertyValues pvs = mbd.getPropertyValues();
if(bw == null) {
if(!((PropertyValues)pvs).isEmpty()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
} else {
boolean continueWithPropertyPopulation = true;
if(!mbd.isSynthetic() && this.hasInstantiationAwareBeanPostProcessors()) {
Iterator var6 = this.getBeanPostProcessors().iterator();
while(var6.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var6.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
//是否继续进行属性填充 if(!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
//不继续
continueWithPropertyPopulation = false;
break;
}
}
}
}
//判断是否继续
if(continueWithPropertyPopulation) {
if(mbd.getResolvedAutowireMode() == 1 || mbd.getResolvedAutowireMode() == 2) {
MutablePropertyValues newPvs = new MutablePropertyValues((PropertyValues)pvs);
if(mbd.getResolvedAutowireMode() == 1) {
//根据名称自动注入
this.autowireByName(beanName, mbd, bw, newPvs);
}
查看该方法autowireByName
protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
//找到需要依赖注入的属性
String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw);
String[] var6 = propertyNames;
int var7 = propertyNames.length;
for(int var8 = 0; var8 < var7; ++var8) {
String propertyName = var6[var8];
//如果包含这个属性的bean
if(this.containsBean(propertyName)) {
//获取这个bean的实例
Object bean = this.getBean(propertyName);
pvs.add(propertyName, bean);
//注册依赖
this.registerDependentBean(propertyName, beanName);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Added autowiring by name from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
}
} else if(this.logger.isTraceEnabled()) {
this.logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName + "' by name: no matching bean found");
}
}
}
接下来看根据类型自动注入
if(mbd.getResolvedAutowireMode() == 2) {
//根据类型自动注入
this.autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
进入该方法
protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {
TypeConverter converter = this.getCustomTypeConverter();
if(converter == null) {
converter = bw;
}
Set<String> autowiredBeanNames = new LinkedHashSet(4);
//找到需要注入的属性
String[] propertyNames = this.unsatisfiedNonSimpleProperties(mbd, bw);
String[] var8 = propertyNames;
int var9 = propertyNames.length;
for(int var10 = 0; var10 < var9; ++var10) {
String propertyName = var8[var10];
try {
PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
if(!Object.class.equals(pd.getPropertyType())) {
//探测指定的set方法
MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
boolean eager = !PriorityOrdered.class.isAssignableFrom(bw.getWrappedClass());
DependencyDescriptor desc = new AbstractAutowireCapableBeanFactory.AutowireByTypeDependencyDescriptor(methodParam, eager);
//解析指定beanName的属性所匹配的所用bean值存到autowiredBeanNames中
Object autowiredArgument = this.resolveDependency(desc, beanName, autowiredBeanNames, (TypeConverter)converter);
我们来看一下这个方法,这是个子类的方法
public Object resolveDependency(DependencyDescriptor descriptor, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException {
descriptor.initParameterNameDiscovery(this.getParameterNameDiscoverer());
if(descriptor.getDependencyType().equals(ObjectFactory.class)) {
//ObjectFactory类注入的特殊处理
return new DefaultListableBeanFactory.DependencyObjectFactory(descriptor, beanName);
} else if(descriptor.getDependencyType().equals(javaxInjectProviderClass)) {
return (new DefaultListableBeanFactory.DependencyProviderFactory(null)).createDependencyProvider(descriptor, beanName);
} else {
Object result = this.getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(descriptor, beanName);
if(result == null) {
// 通用处理,处理了各种集合类型
result = this.doResolveDependency(descriptor, beanName, autowiredBeanNames, typeConverter);
}
return result;
}
}
总之,在通过类型匹配找到bean进行注入,如果匹配到了多个同种类型,那么就要区分他们的beanName,如果需要匹配的是集合类型,spring会找到容器中所有该类型的bean进行注入,返回集合类型.但是我们要注意,如果用注解注入,我们需要在配置文件中加入
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
而且容器要用ApplicationContext
if(autowiredArgument != null) {
//添加至属性集合
pvs.add(propertyName, autowiredArgument);
}
Iterator var17 = autowiredBeanNames.iterator();
while(var17.hasNext()) {
String autowiredBeanName = (String)var17.next();
//注册依赖 this.registerDependentBean(autowiredBeanName, beanName);
if(this.logger.isDebugEnabled()) {
this.logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" + propertyName + "' to bean named '" + autowiredBeanName + "'");
}
}
autowiredBeanNames.clear();
}
} catch (BeansException var19) {
throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, var19);
}
}
}
接着属性提取完后的工作,这时候PropertyValues已经拿到了需要以来的属性
//后处理器是否已经初始化
boolean hasInstAwareBpps = this.hasInstantiationAwareBeanPostProcessors();
//是否需要依赖检查
boolean needsDepCheck = mbd.getDependencyCheck() != 0;
if(hasInstAwareBpps || needsDepCheck) {
PropertyDescriptor[] filteredPds = this.filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if(hasInstAwareBpps) {
Iterator var9 = this.getBeanPostProcessors().iterator();
while(var9.hasNext()) {
BeanPostProcessor bp = (BeanPostProcessor)var9.next();
if(bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor)bp;
//对所有需要依赖检查的属性进行后处理
pvs = ibp.postProcessPropertyValues((PropertyValues)pvs, filteredPds, bw.getWrappedInstance(), beanName);
if(pvs == null) {
return;
}
}
}
}
if(needsDepCheck) {
this.checkDependencies(beanName, mbd, filteredPds, (PropertyValues)pvs);
}
}
//将属性应用到bean中
this.applyPropertyValues(beanName, mbd, bw, (PropertyValues)pvs);
}
}
}
现在属性注入已经完成了,继续加载原来bean的工作
if(exposedObject != null) {
//调用初始化方法,比如init-method
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
}
}
/*省略一些异常处理代码*/
我们来查看这个初始化bean方法
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
if(System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
AbstractAutowireCapableBeanFactory.this.invokeAwareMethods(beanName, bean);
return null;
}
}, this.getAccessControlContext());
} else {
//对于实现Aware系列接口的bean的处理,实现这些接口的bean,调用这个方法会向bean中注入相应的资源。
this.invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if(mbd == null || !mbd.isSynthetic()) {
//应用后处理bean
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}
try {
//调用用户自定义的init方法
this.invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable var6) {
throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", var6);
}
if(mbd == null || !mbd.isSynthetic()) {
//应用初始化后处理bean
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
返回创建bean的过程
if(earlySingletonExposure) {
Object earlySingletonReference = this.getSingleton(beanName, false);
//earlySingletonReference 只有在检测到循环依赖的情况下才不会为空
if(earlySingletonReference != null) {
//如果这两个对象一样说明没有被增强
if(exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if(!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {
String[] dependentBeans = this.getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);
String[] var12 = dependentBeans;
int var13 = dependentBeans.length;
for(int var14 = 0; var14 < var13; ++var14) {
//检测依赖
String dependentBean = var12[var14];
if(!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
//因为bean创建后其所依赖的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 " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
try {
//根据scope注册bean this.registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
} catch (BeanDefinitionValidationException var16) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);
}
}
现在真正的创建完了bean
} catch (BeanCreationException var14) {
BeanCreationException ex = var14;
if(recordSuppressedExceptions) {
Iterator var7 = this.suppressedExceptions.iterator();
while(var7.hasNext()) {
Exception suppressedException = (Exception)var7.next();
ex.addRelatedCause(suppressedException);
}
}
throw ex;
} finally {
if(recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
this.afterSingletonCreation(beanName);
}
//添加到单例集合
this.addSingleton(beanName, singletonObject);
}
return singletonObject != NULL_OBJECT?singletonObject:null;
}
}
下面又是整个getBean的过程,和之前的代码很相似。
bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if(mbd.isPrototype()) {
var11 = null;
Object prototypeInstance;
try {
this.beforePrototypeCreation(beanName);
prototypeInstance = this.createBean(beanName, mbd, args);
} finally {
this.afterPrototypeCreation(beanName);
}
bean = this.getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
Scope 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>() {
public Object getObject() throws BeansException {
AbstractBeanFactory.this.beforePrototypeCreation(beanName);
Object var1;
try {
var1 = AbstractBeanFactory.this.createBean(beanName, mbd, args);
} finally {
AbstractBeanFactory.this.afterPrototypeCreation(beanName);
}
return var1;
}
});
bean = this.getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}