上篇咱们聊到了doCreateBean方法,在里面了解到先进行获取bean的实例,然后给属性赋值,再调用bean的初始化方法,如果需要的话会把bean注册到销毁容器中。接下来咱们了解下实例化的流程
spring实例化有哪些方式
可以试想下,如果让咱们自己实现实例化bean,会如何做?
- 通过supplier
- 通过FactoryBean
- 通过factory-method
- 通过构造方法(反射)
- …
源码
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
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());
}
//bean的创建方式一,通过supplier
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//bean的创建方式二,通过FactoryBean或Factory-method
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 是否使用工厂方法
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);
}
}
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 前面supplier,FactoryBean,factory-method ,构造都没选择上,使用默认的构造进行创建对象
return instantiateBean(beanName, mbd);
}
AbstractAutowireCapableBeanFactory.obtainFromSupplier 通过supplier
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
Object instance;
// currentlyCreatedBean是一个ThreadLocal
String outerBean = this.currentlyCreatedBean.get();
// 把当前bean名称设置进去
this.currentlyCreatedBean.set(beanName);
try {
// 调用Supplier的get方法,获取bean实例
instance = instanceSupplier.get();
}finally {
// 这里已经是最后一层调用,如果ThreadLocal中有值,再赋值回去,不耽搁在别的地方进行调用
if (outerBean != null) {
this.currentlyCreatedBean.set(outerBean);
}else {
// 未使用到ThreadLocal,清空里面的数据,方便垃圾回收
this.currentlyCreatedBean.remove();
}
}
if (instance == null) {
instance = new NullBean();
}
// 创建一个包装类
BeanWrapper bw = new BeanWrapperImpl(instance);
// 初始化bean的包装器,也就是调用registerCustomEditors方法
initBeanWrapper(bw);
return bw;
}
AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod 通过FactoryBean
protected BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
// 使用构造器解析器用工厂方法进行实例化
return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
}
AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod 使用工厂方法进行实例化
public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
BeanWrapperImpl bw = new BeanWrapperImpl();
// 初始化包装器
this.beanFactory.initBeanWrapper(bw);
Object factoryBean;
Class<?> factoryClass;
boolean isStatic;
// 获取FactoryBean的bean名称,咱们可以FactroyBean的getObject创建bean,而FactoryBean也是需要创建的
String factoryBeanName = mbd.getFactoryBeanName();
// 如果存在FactoryBean工厂名称,说明创建的bean是通过FactoryBean创建的bean
if (factoryBeanName != null) {
// 这时候创建的bean不能和FactoryBean的bean是同一个,这样没有意义
if (factoryBeanName.equals(beanName)) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,"factory-bean reference points back to the same bean definition");
}
// 通过beanFactory创建工厂(有可能已经创建过了)
factoryBean = this.beanFactory.getBean(factoryBeanName);
if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
throw new ImplicitlyAppearedSingletonException();
}
// 注册依赖关系
this.beanFactory.registerDependentBean(factoryBeanName, beanName);
// 获取FactoryBean类型
factoryClass = factoryBean.getClass();
// 标识不是通过 factory-method=“” 指定的方法来创建
isStatic = false;
}else {
// 通过 factory-method=“” 指定的方法来创建
// 那么此时bean定义信息必须要有beanclass
if (!mbd.hasBeanClass()) {
throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,"bean definition declares neither a bean class nor a factory-bean reference");
}
// 标识不识通过FactoryBean来创建的
factoryBean = null;
// 是通过通常方法创建的
factoryClass = mbd.getBeanClass();
// 并且这个方法是静态的(非静态的指定了也会报错不是~~~)
isStatic = true;
}
Method factoryMethodToUse = null;
ArgumentsHolder argsHolderToUse = null;
// 声明参数
Object[] argsToUse = null;
// 判断有无参数,咱们调用静态方法的时候有可能会传递参数的
if (explicitArgs != null) {
// 标识使用有参的方法创建
argsToUse = explicitArgs;
}else {
// 使用无参的方法创建
//
Object[] argsToResolve = null;
synchronized (mbd.constructorArgumentLock) {
// 获取工厂方法
factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
// 得到构造参数
argsToUse = mbd.resolvedConstructorArguments;
if (argsToUse == null) {
// 如果有替换的参数,那么进行替换
argsToResolve = mbd.preparedConstructorArguments;
}
}
}
if (argsToResolve != null) {
// 如果有替换的参数,那么进行替换
argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve);
}
}
// 如果没有工厂方法,或者无参
if (factoryMethodToUse == null || argsToUse == null) {
// 确定工厂类
factoryClass = ClassUtils.getUserClass(factoryClass);
// 存储符合条件的方法
List<Method> candidates = null;
if (mbd.isFactoryMethodUnique) {
if (factoryMethodToUse == null) {
factoryMethodToUse = mbd.getResolvedFactoryMethod();
}
if (factoryMethodToUse != null) {
candidates = Collections.singletonList(factoryMethodToUse);
}
}
// 如果没有选出指定的方法
if (candidates == null) {
candidates = new ArrayList<>();
// 获取mbd对应的bean对应所有方法
Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
for (Method candidate : rawCandidates) {
//如果找到了,那么添加到方法的集合中
if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
candidates.add(candidate);
}
}
}
// 无参的静态方法,factory-method 指定的方法必须是静态的
if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Method uniqueCandidate = candidates.get(0);
if (uniqueCandidate.getParameterCount() == 0) {
mbd.factoryMethodToIntrospect = uniqueCandidate;
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
// 通过反射执行指定的方法
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
// 多个方法进行排序
if (candidates.size() > 1) {
candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
}
ConstructorArgumentValues resolvedValues = null;
// 是否满足
boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
// 从这里可以看出,有好几个方法被匹配上了,但是到底选择哪个呢?
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Method> ambiguousFactoryMethods = null;
// 最小的参数个数
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}else {
// 先确定是否有参数
if (mbd.hasConstructorArgumentValues()) {
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 确定参数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
} else {
minNrOfArgs = 0;
}
}
// 到这里咱们知道,有多个重名的方法,0个或多个参数,但是不知道到底使用哪一个参数进行创建
// 有兴趣的可以看看下面的逻辑,个人觉得没必要浪费脑汁~~~
// 这段逻辑就是为了解决一个事情,选出最优的那个方法进行创建
LinkedList<UnsatisfiedDependencyException> causes = null;
for (Method candidate : candidates) {
int parameterCount = candidate.getParameterCount();
if (parameterCount >= minNrOfArgs) {
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
if (explicitArgs != null) {
// Explicit arguments given -> arguments length must match exactly.
if (paramTypes.length != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
} else {
// Resolved constructor arguments: type conversion and/or autowiring necessary.
try {
String[] paramNames = null;
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
paramNames = pnd.getParameterNames(candidate);
}
argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw,paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
} catch (UnsatisfiedDependencyException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Ignoring factory method [" + candidate + "] of bean '" + beanName + "': " + ex);
}
// Swallow and try next overloaded factory method.
if (causes == null) {
causes = new LinkedList<>();
}
causes.add(ex);
continue;
}
}
int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
if (typeDiffWeight < minTypeDiffWeight) {
factoryMethodToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousFactoryMethods = null;
}else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight && !mbd.isLenientConstructorResolution() && paramTypes.length == factoryMethodToUse.getParameterCount() && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
if (ambiguousFactoryMethods == null) {
ambiguousFactoryMethods = new LinkedHashSet<>();
ambiguousFactoryMethods.add(factoryMethodToUse);
}
ambiguousFactoryMethods.add(candidate);
}
}
}
if (factoryMethodToUse == null || argsToUse == null) {
if (causes != null) {
UnsatisfiedDependencyException ex = causes.removeLast();
for (Exception cause : causes) {
this.beanFactory.onSuppressedException(cause);
}
throw ex;
}
List<String> argTypes = new ArrayList<>(minNrOfArgs);
if (explicitArgs != null) {
for (Object arg : explicitArgs) {
argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
}
} else if (resolvedValues != null) {
Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
valueHolders.addAll(resolvedValues.getGenericArgumentValues());
for (ValueHolder value : valueHolders) {
String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
argTypes.add(argType);
}
}
String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
throw new BeanCreationException(mbd.getResourceDescription(), beanName,"No matching factory method found on class [" + factoryClass.getName() + "]: " + (mbd.getFactoryBeanName() != null ? "factory bean '" + mbd.getFactoryBeanName() + "'; " : "") + "factory method '" + mbd.getFactoryMethodName() + "(" + argDesc + ")'. " + "Check that a method with the specified name " + (minNrOfArgs > 0 ? "and arguments " : "") + "exists and that it is " + (isStatic ? "static" : "non-static") + ".");
}else if (void.class == factoryMethodToUse.getReturnType()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid factory method '" + mbd.getFactoryMethodName() + "' on class [" + factoryClass.getName() + "]: needs to have a non-void return type!");
} else if (ambiguousFactoryMethods != null) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Ambiguous factory method matches found on class [" + factoryClass.getName() + "] " + "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " + ambiguousFactoryMethods);
}
if (explicitArgs == null && argsHolderToUse != null) {
mbd.factoryMethodToIntrospect = factoryMethodToUse;
argsHolderToUse.storeCache(mbd, factoryMethodToUse);
}
}
// 到这里说明选举出来到底用哪个方法进行创建了
bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
return bw;
}