1.createInstance方法,Spring给我们提供了三种创建bean实例的方式,1.工厂方法2.有参构造器,3.无参构造器
逻辑很简单
a.首先判断工厂方法是否存在,如果有则使用工厂方法实例化bean
b.判断程序有没有传自定义参数获取bean如果没有判断有没有解析过构造函数,如果有的话,判断是否为构造函数解析过参数
如果没有解析过则认为,人家用的是默认构造器即无参的直接简单实例化bean,否则需要使用autowireConstrucotr方法去创建bean
c.程序往下执行会判断当前bean是否有构造参数/bean中定义是否用autwireConstructor或者bean定义包含构造参数函数或者自定义传参不为null都需要使用autowireConstructor创建bean
d.使用无参构造初始化bean
2.instantiateUsingFactoryMethod(autowireConstructor),即使用工厂方法初始化bean将bean的初始化委托给了ConstructorResolver的instantiateUsingFactoryMethod方法,使用构造器创建对象的方法委托给了autowireConstructor,
public BeanWrapper autowireConstructor(final String beanName, final RootBeanDefinition mbd,
Constructor<?>[] chosenCtors, final Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
//使用在此工厂注册的自定义编辑器初始化给定的BeanWrapper。 为将要创建和填充bean实例的BeanWrappers调用
//初始化bean创建和填充bean所需要使用的propertyEditors
this.beanFactory.initBeanWrapper(bw);
//要使用的构造函数
Constructor<?> constructorToUse = null;
//持有参数
ArgumentsHolder argsHolderToUse = null;
//待使用的参数
Object[] argsToUse = null;
//如果用户传入了指定参数
if (explicitArgs != null) {
//直接赋值
argsToUse = explicitArgs;
}
else {
//从配置文件中解析
Object[] argsToResolve = null;
//看看是否已经解析过了
synchronized (mbd.constructorArgumentLock) {
//已经解析过的构造参数
constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
//已经解析过了参数
if (constructorToUse != null && mbd.constructorArgumentsResolved) {
// 直接获取
argsToUse = mbd.resolvedConstructorArguments;
//还没有解析到
if (argsToUse == null) {
//使用配置的构造参数后面会解析
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
//配置的构造参数不为null,譬如构造函数要求使用int,但是我们原始参数值可能是String类型"1"
if (argsToResolve != null) {
//解析配置的构造参数为匹配构造器的参数
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
}
}
//构造器还未解析,这种情况就是没有从缓存取到可用的构造器了嘿嘿
if (constructorToUse == null) {
// Need to resolve the constructor.
//判断是否需要构造器注入
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.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) {
//beanClass
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 {
//获取ConstructorProperties注释上的paramNames
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 (this.beanFactory.logger.isTraceEnabled()) {
this.beanFactory.logger.trace(
"Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next constructor.
if (causes == null) {
causes = new LinkedList<UnsatisfiedDependencyException>();
}
causes.add(ex);
continue;
}
}
else {
//如果构造器的长度和给定参数长度不一致直接进入下一轮循环
if (paramTypes.length != explicitArgs.length) {
continue;
}
//创建ArgumentsHolder
argsHolder = new 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<Constructor<?>>();
ambiguousConstructors.add(constructorToUse);
}
ambiguousConstructors.add(candidate);
}
}
//解析结束后待使用构造参数还未Null,将异常抛出
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)");
}
//如果不以宽松模式解析并且相似的构造函数存在,抛出异常,给出hint提示
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 {
Object beanInstance;
if (System.getSecurityManager() != null) {
final Constructor<?> ctorToUse = constructorToUse;
final Object[] argumentsToUse = argsToUse;
beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
return beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, beanFactory, ctorToUse, argumentsToUse);
}
}, beanFactory.getAccessControlContext());
}
else {
//实例化Bean
beanInstance = this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, constructorToUse, argsToUse);
}
bw.setBeanInstance(beanInstance);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via constructor failed", ex);
}
}
个人认为解析的过程和保存的缓存过程理解下就好了,没必要深究,上述方法我们比较在意的地方是bean的实例化,如果是我自己开发这种ioc容器肯定会直接使用反射创建了,但是Spring没有这么做
这是因为我们可以在bean中配置lookup-method和replacemethod,spring需要判断bean defition属性中是否存在,如果存在则需要生成代理对象
对于instantiateWithMethodInjection方法我们现在就不进行深入了。
3.我们回到doCreateBean方法在创建bean成功后,Spring给我们提供了一个扩展点
可以通过implement MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法进行扩展
4.对于循环依赖的解决,可以看到在还没有进行bean属性赋值前暴露一个objectFactory
其中getEarlyBeanReference方法
仅仅是通过 SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法将上面创建的bean引用暴露出去,如果后面程序继续调用方法
因为是同一个引用所以原bean做了赋值,依赖方的bean也会 赋值。