实例化
AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// 解析出bd中的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);
}
// 如果是工厂方放创建的走这步,@Bean注解也走这步
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);
}
}
/*
可以实现SmartInstantiationAwareBeanPostProcessor接口器,可以指定构造器
spring有一个实现类,该类中有选择候选构造器的逻辑
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/*条件只要满足一项就可以
1. 解析出的构造函数不是null
2. 注入模式是构造器入住
3. bd中有构造器参数的属性
4. 有构造器的参数值
*/
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 优先推荐的构造器
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 用无参构造函数实例化
return instantiateBean(beanName, mbd);
}
如果已经解析过,要是有构造函数参数,说明实例化的通过有参构造函数;如果没有参数,使用的是默认的构造函数。
如果没有解析过,进入解析逻辑:从所有构造函数中找候选的构造器;如果有候选的,或者注入类型是构造器注入,或者有构造器参数,会走特殊构造器的逻辑,否则就是默认构造器的逻辑。。
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
// 调用的是SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法
// 如果返回了候选的构造器,就返回。
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
return null;
}
AutowiredAnnotationBeanPostProcessor#determineCandidateConstructors
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
throws BeanCreationException {
// 标注有@LookUp注解的,不分析了
。。。。
// 从缓存中找候选构造器
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
// 如果缓存中没有,进入寻找逻辑,如果有,直接返回。
if (candidateConstructors == null) {
// Fully synchronized resolution now...
synchronized (this.candidateConstructorsCache) {
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
// 双检查,得到所有的构造器
rawCandidates = beanClass.getDeclaredConstructors();
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Resolution of declared constructors on bean Class [" + beanClass.getName() +
"] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
}
List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
// 主要用户适配android
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
// 遍历构造器
for (Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
nonSyntheticConstructors++;
}
else if (primaryConstructor != null) {
continue;
}
// 这里的逻辑是如果构造器有@autowired @value注解,返回注解信息。
MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);
if (ann == null) {
// 如果没有注解,找到父类,查看父类是否有
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor =
userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = findAutowiredAnnotation(superCtor);
}
catch (NoSuchMethodException ex) {
// Simply proceed, no equivalent superclass constructor found...
}
}
}
// 如果有注解信息,就把这个构造器加入到候选构造器中
if (ann != null) {
// 如果有多个用@autowired注解标注的构造器,并且required都是true就会抛异常。
// required为true的构造器只能有一个
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
// 查看autowired注解中的属性required的值
boolean required = determineRequiredStatus(ann);
if (required) {
// 如果已经有了候选的,抛异常
if (!candidates.isEmpty()) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructors: " + candidates +
". Found constructor with 'required' Autowired annotation: " +
candidate);
}
requiredConstructor = candidate;
}
candidates.add(candidate);
}
// 总结:如果有注解标注,如果都是false的,加入集合;如果有true的的情况下,还有有注解标注的,无论true或者false,都会抛异常。
// 那么集合中只有两种情况:1. 只有一个用注解标注,同时是true的
// 2. 有多个用注解标注,但是都是false的。
// 如果从中,有默认的构造器,设置变量。
else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
// 遍历值找两种构造器,1.默认构造器,2.有注解的构造器。
if (!candidates.isEmpty()) {
// Add default constructor to list of optional constructors, as fallback.
if (requiredConstructor == null) {
if (defaultConstructor != null) {
// 如果有默认的,加入到集合中,前提是required的值是true.
candidates.add(defaultConstructor);
}
else if (candidates.size() == 1 && logger.isInfoEnabled()) {
logger.info("Inconsistent constructor declaration on bean with name '" + beanName +
"': single autowire-marked constructor flagged as optional - " +
"this constructor is effectively required since there is no " +
"default constructor to fall back to: " + candidates.get(0));
}
}
// 如果有候选的,返回候选的
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
else if (rawCandidates.length == 1 && rawCandidates[0].getParameterCount() > 0) {
// 如果只有一个构造器,并且还是有参的
candidateConstructors = new Constructor<?>[] {rawCandidates[0]};
}
// 剩下的这两个适配android
else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
}
else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
candidateConstructors = new Constructor<?>[] {primaryConstructor};
}
else {
// 否则返回一个无数据的空数据
candidateConstructors = new Constructor<?>[0];
}
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
// 如果有数据,返回数据,没有数据的话返回null
return (candidateConstructors.length > 0 ? candidateConstructors : null);
}
流程梳理
用@autowired指定构造器,如果required是true,那么只能指定一个,否则就会报错。如果是false,那么可以指定多个构造器。
那么该方法实现的是什么逻辑呢?就是找用@autowired注解标注的构造器,如果有,就返回。如果没有,但只有一个有参的构造器,那么就返回这个有参的构造器。剩下都返回null.
默认构造器实例化对象
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#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 {
// 根据不同的策略实例化bean
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);
}
}
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// 没有继承关系
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);
}
}
}
// 默认构造函数。反射
// instantiateClass(Constructor ctor, Object... args),传入构造器和对应的参数进行实例化。
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
简单的说就是获取到默认构造函数,直接反射得到对象。
通过有参构造函数实例化对象
如果没有候选的构造函数,spring要自己筛选合适的构造器。。。
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;
/*
有参数传入,说明是用户通过getBean(name,args)了。
*/
if (explicitArgs != null) {
argsToUse = explicitArgs;
}
else {
/*
之前解析过,bd中取构造函数和构造函数的参数实例。
*/
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) {
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
主要是解析参数,如果没有传进来参数,就解析bd中存储的,如果bd中也没有存储就返回null
// 实例话对象要有构造器和参数,只要一个没有就要自己解析。。
if (constructorToUse == null || argsToUse == null) {
// 得到创建来的构造器数组
Constructor<?>[] candidates = chosenCtors;
// 如果没有,就得到该类的所有的构造器
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
// 如果传入的构造函数为null, 反射获得所有的构造函数
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);
}
}
// 只有一个构造函数,参数个数是0,直接进行实例化。
if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
Constructor<?> uniqueCandidate = candidates[0];
if (uniqueCandidate.getParameterCount() == 0) {
synchronized (mbd.constructorArgumentLock) {
mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
mbd.constructorArgumentsResolved = true;
mbd.resolvedConstructorArguments = EMPTY_ARGS;
}
bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
return bw;
}
}
构造器,如果没有合适的构造器传进来,直接获得该类的所有构造器,如果有默认构造器的话,直接实例化
// 解析bd中的构造器参数。
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
// 如果没有用户传入,解析getConstructorArgumentValues中的参数。应该是解析bd是放入的。
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
// 解析参数,就是从cargs 解析出参数,放入resolvedValues
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
解析bd中的构造器参数,如果有数据就将数据放入resolvedValues 中。
// 排序,先public的,之后参数个数有多到少
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
Deque<UnsatisfiedDependencyException> causes = null;
// 解析构造函数
for (Constructor<?> candidate : candidates) {
int parameterCount = candidate.getParameterCount();
// 构造器和参数都有,参数比构造器的参数还多,说明已经找到了,返回,实例化
if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
// Already found greedy constructor that can be satisfied ->
// do not look any further, there are only less greedy constructors left.
break;
}
if (parameterCount < minNrOfArgs) {
continue;
}
ArgumentsHolder argsHolder;
Class<?>[] paramTypes = candidate.getParameterTypes();
// 没有args传入,解析参数。
if (resolvedValues != null) {
try {
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
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, candidates.length == 1);
}
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 ArrayDeque<>(1);
}
causes.add(ex);
continue;
}
}
else {
// 如果用户传进来参数,则进行严格匹配
if (parameterCount != explicitArgs.length) {
continue;
}
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<>();
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);
}
// 找到合适的存储在bd中
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
spring自己解析构造器:排序构造器,public ,protect,private ,同样修饰符的按照参数个数排序,多的排在前面。便利构造器,根据构造器的参数,从容器中取出实例对象。根绝权重,找到最合适的。如果有多个权重一样的会抛异常。
public static int getTypeDifferenceWeight(Class<?>[] paramTypes, Object[] args) {
int result = 0;
for (int i = 0; i < paramTypes.length; i++) {
if (!ClassUtils.isAssignableValue(paramTypes[i], args[i])) {
return Integer.MAX_VALUE;
}
if (args[i] != null) {
Class<?> paramType = paramTypes[i];
Class<?> superClass = args[i].getClass().getSuperclass();
while (superClass != null) {
if (paramType.equals(superClass)) {
result = result + 2;
superClass = null;
}
else if (ClassUtils.isAssignable(paramType, superClass)) {
result = result + 2;
superClass = superClass.getSuperclass();
}
else {
superClass = null;
}
}
if (paramType.isInterface()) {
result = result + 1;
}
}
}
return result;
}
看下权重是怎么计算的,就是解析出来的参数类型和构造器的类型做比较。实际值的类型离构造器的参数类型越远,全总值越大,那么这个构造器的优先级越低。
推荐阅读:
【小家Spring】AbstractBeanFactory#getBean()、doGetBean完成Bean的初始化、实例化,以及BeanPostProcessor后置处理器源码级详细分析