spring源码实例化bean createBeanInstance

21 篇文章 1 订阅
11 篇文章 0 订阅

前篇文章传送门

上篇咱们聊到了doCreateBean方法,在里面了解到先进行获取bean的实例,然后给属性赋值,再调用bean的初始化方法,如果需要的话会把bean注册到销毁容器中。接下来咱们了解下实例化的流程

spring实例化有哪些方式

可以试想下,如果让咱们自己实现实例化bean,会如何做?

  1. 通过supplier
  2. 通过FactoryBean
  3. 通过factory-method
  4. 通过构造方法(反射)
源码
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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值