剑指spring源码(四)

剑指spring源码(四)

前言

距离上一篇spring源码系列文章已经三个月了,这段时间有点懒,更新频率大大下降了,甚至几度想要放弃这个系列,因为感觉真的不是我能掌控的,spring太精妙了,经过前面几篇博客的铺垫,我们这篇来聊一聊getBean时期spring都干了什么,都有哪几个后置处理器,都是干嘛的,还有循环引用的问题,以及什么情况的循环引用可以解决

ioc

refresh->
finishBeanFactoryInitialization(beanFactory);->
beanFactory.preInstantiateSingletons();->
getBean(beanName);->
doGetBean()

doGetBean关键代码如下

	//singletonObjects->earlySingletonObjects->singletonFactories
	//三级缓存获取bean
	Object sharedInstance = getSingleton(beanName);
	
	//创建bean生命周期
	if (mbd.isSingleton()) {
		sharedInstance = getSingleton(beanName, () -> {
		return createBean(beanName, mbd, args);
		});
	}

第一个getSingleton代码如下:三级缓存主要作用是解决循环引用

	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		//单例池中拿 第一级缓存
		Object singletonObject = this.singletonObjects.get(beanName);
		//单例池没有
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			//锁住单例池
			synchronized (this.singletonObjects) {
				//early中拿 第三级缓存
				singletonObject = this.earlySingletonObjects.get(beanName);
				//第级三缓存拿不到
				if (singletonObject == null && allowEarlyReference) {
					//singletonFactories拿 ,第二级缓存
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						//第级二缓存拿到了
						singletonObject = singletonFactory.getObject();
						//put到第三级缓存
						this.earlySingletonObjects.put(beanName, singletonObject);
						//移除二级缓存
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}

第二个getSingleton会回调createBean方法,createBean关键代码如下

第一次执行后置处理器-aop切面aspect

			
			//InstantiationAwareBeanPostProcessor
			// postProcessBeforeInstantiation 实例化前(实例化范围大,从第一次执行后置处理器就执行了,贯穿8次后置处理器)
			//postProcessAfterInitialization  初始化后(初始化范围小,第七次执行后置处理器回调了BeforeInitialization)
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		
		//resolveBeforeInstantiation代码如下
		protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
				//遍历所有的InstantiationAwareBeanPostProcessor执行postProcessBeforeInstantiation方法,
				//第一次执行后置处理器 这个后置处理器99.9%返回null,除非我们覆盖postProcessBeforeInstantiation
				//aop相关 核心缓存切面信息,把切面myAspect标志为不能代理状态 ,如果没有aop可以忽略这一次的后置处理器
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					//这里如果bean不空,则会继续执行一次postProcessAfterInitialization方法
					//为什么要执行这个,因为这是spring的规则,初始化后就得执行这个方法
					//但是为什么spring不设计成执行postProcessAfterInstantiation方法呢?
					//因为postProcessAfterInstantiation方法返回true代表后续会进行DI填充,
					//而如果此时返回了bean不为null,后续根本就不会DI,所以没有意义
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
//第一次后置处理器调用 目的是 this.advisedBeans.put(cacheKey, Boolean.FALSE);这一行代码 即把切面aspect标为不需要代理的状态
	//如果自己代理自己会发生很毁灭性的事情,无限递归stackOverFlow
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		//beanName不为null和""的时候cacheKey = beanName(factoryBean的情况要加&) 否则cacheKey=beanClass
		// TODO  beanName什么情况是null???
		Object cacheKey = getCacheKey(beanClass, beanName);
		//beanName不为null和"" 或者 targetSourcedBeans没有beanName(后者几乎都是true)
		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			//advisedBeans---Map<Object, Boolean>
			//Object是缓存key(beanName),false代表此bean不要进行代理
			// (这里不要代理有三个意思,一个是不要代理,一个是不能代理(Aspect),还一个是已经被代理(appConfig))
			// true代表要进行代理

			//advisedBeans已经有此beanName了,直接return null
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			//advice/pointcut/advisor/aspect都是InfrastructureClass ,都不要被代理
			//shouldSkip 缓存myAspect切面信息
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				//不要代理此beanName对应的bean  
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		//TODO 这段代码片几乎没有调用到,除非自定义TargetSource???
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}

下面以一个例子说明第一个后置处理器的作用以及spring的设计原理

@Component
public class IABeanPostProcessor  implements InstantiationAwareBeanPostProcessor {

	//bean的产生:
	// 空对象,第一次后置处理器,
	// 第二次:决策构造器,
	// 第三次:merge,
	// 第四次:添加到单例池,提前暴露空对象
	//第五次:实例化后的后置处理器,bean是否需要完成属性填充
	//第六次:属性填充
	//第七八次:初始化前后的后置处理器
	//第九次:销毁
	//初始化范围小,在属性填充后执行
	//初始化前   第七次执行后置处理器回调


	//实例化 范围更大 贯穿9次后置处理器中
	//实例化前  第一次执行后置处理器resolveBeforeInstantiation 会从这里返回  但是结束时还要回调postProcessAfterInitialization
	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return "Instant before";
	}

	//初始化后  第八次执行后置处理器回调,
	//第一次执行后置处理器回调(需要postProcessBeforeInstantiation返回不为null)
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return "init after";
	}

	//第五次执行后置处理器
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true; //bean需要完成属性填充
	}

}


	public static void main(String[] args) {
		AnnotationConfigApplicationContext app =
				new AnnotationConfigApplicationContext(AppConfig.class);
		System.out.println("ioc容器创建完毕");
		Object userService = app.getBean("userService");
		//第一次后置处理器执行IABeanPostProcessor的postProcessBeforeInstantiation,返回bean不为null
		//再执行postProcessAfterInitialization,所以下面输出init after
		//当你把 postProcessAfterInitialization注释掉,返回的就是Instant before
		System.out.println(userService);
	}

第二次执行后置处理-推断构造器

第二次执行后置处理器是决策构造器,入口为AbstractAutowireCapableBeanFactory的doCreateBean方法的
instanceWrapper = createBeanInstance(beanName, mbd, args);这行代码
我们来看看createBeanInstance这个方法干了什么
我注意到这段代码作用·是提高原型bean的创建速率,不再需要每次都去推断构造器

		// 为重复创建原型bean提供快捷方式
		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		//一般args==null
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				//第一次resolvedConstructorOrFactoryMethod为null,
				//第二次进if
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//第一次不进if
		//第二次进if
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				//第二次进这里,不再需要推断构造器了
				return instantiateBean(beanName, mbd);
			}
		}
		//后续代码决策构造器,构造对象后给mbd.resolvedConstructorOrFactoryMethod赋值(createBeanInstance最后一行代码赋的值)

下面这行代码就是第二次后置处理器,推断构造器,循环遍历beanPostProcessor,执行determineCandidateConstructors方法

  //第二次后置处理器
  Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);

上面代码其实就是调用了AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors
除去lookup处理,引起我注意的是
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
这行代码,这个candidateConstructorsCache是什么,他是一个Map<Class,Constructor[]>,可是这个缓存存在的意义是什么?原型bean根本走不到这里,在前面spring就对原型bean优化处理过了
单例bean第二次调用直接从单例池取出来,更加走不到这里了
那就是说常规手段根本不可能使用到此缓存,此缓存暂时不理解

					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);
					}
					//合格的构造器,我的理解是candidates.size要么是0要么是1(在没有autowired的情况)
					List<Constructor<?>> candidates = new ArrayList<>(rawCandidates.length);
					//@Autowired(true)的构造器
					Constructor<?> requiredConstructor = null;
					//默认无参构造器
					Constructor<?> defaultConstructor = null;
					//涉及kotlin知识,我们只需要明白常规java项目primaryConstructor一定是null
					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
					//不是合成的构造器数量,不懂什么意思,但是常规构造器写法不管参数多少candidate.isSynthetic()都是false
					int nonSyntheticConstructors = 0;
					//遍历所有构造器
					for (Constructor<?> candidate : rawCandidates) {
						if (!candidate.isSynthetic()) {
							//每次都会加
							nonSyntheticConstructors++;
						}
						//这个非kotlin环境一定为null
						else if (primaryConstructor != null) {
							continue;
						}
						//找到该构造器Autowired注解属性
						AnnotationAttributes ann = findAutowiredAnnotation(candidate);
						//该构造器没有加Autowired
						if (ann == null) {
							Class<?> userClass = ClassUtils.getUserClass(beanClass);
							//这里什么情况会不等,一帮不会进if
							if (userClass != beanClass) {
								try {
									Constructor<?> superCtor =
											userClass.getDeclaredConstructor(candidate.getParameterTypes());
									ann = findAutowiredAnnotation(superCtor);
								}
								catch (NoSuchMethodException ex) {
									// Simply proceed, no equivalent superclass constructor found...
								}
							}
						}
						//有Autowired注解
						if (ann != null) {
							//我们说requiredConstructor就是存储Autowired(true)的那个构造器
							//已经有requiredConstructor了,又来一个Autowired直接报错
							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);
							//如果是true
							if (required) {
								//合格的构造器集合已经有了,我们说这个构造器集合最多只能有一个,所以直接报错
								//为什么spring设计合格的构造器集合最多只能有一个,因为返回多个给调用方也没用啊,他还是不知道用哪个,
								// 所以决策构造器最好的方式就是要不返回一个,要不返回null(没有autowired的情况)
								if (!candidates.isEmpty()) {
									throw new BeanCreationException(beanName,
											"Invalid autowire-marked constructors: " + candidates +
											". Found constructor with 'required' Autowired annotation: " +
											candidate);
								}
								//给requiredConstructor赋值
								requiredConstructor = candidate;
							}
							//添加到合格构造器集合
							candidates.add(candidate);
						}
						//给默认构造器赋值
						else if (candidate.getParameterCount() == 0) {
							defaultConstructor = candidate;
						}
					}
					//合格构造器集合不空
					if (!candidates.isEmpty()) {
						//Autowried(false)会出现candidates不空,而requiredConstructor的现象
						if (requiredConstructor == null) {
							//添加默认的
							if (defaultConstructor != null) {
								candidates.add(defaultConstructor);
							}
							//candidates只有一个构造器(有参) 
							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]};
					}
					//非kotlin不会进
					else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&
							defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};
					}
					//非kotlin不会进
					else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {
						candidateConstructors = new Constructor<?>[] {primaryConstructor};
					}
					else {
						candidateConstructors = new Constructor<?>[0];
					}
					this.candidateConstructorsCache.put(beanClass, candidateConstructors);
				}
			}
		}
		//要不返回一个要不返回null(如果返回了null,那么调用方用无参实例化就好了)
		return (candidateConstructors.length > 0 ? candidateConstructors : null);

在没有autowried情况下,上面方法的返回只有两种情况
情况一:只有一个构造器(并且含有参数)返回该构造器,这种情况太确定了,只好返回这个,并且参数会给你装配,如果参数不在spring容器,会报错
情况二:除了情况一,都是返回null
spring之所以这么设计在上面代码的注释已经解释了一部分原因,还有一个原因是spring bean的装配模式默认是NO,也就是手动装配,你给了很多的构造器,那些构造器参数spring没办法帮你自动装配。(猜测原因,个人有个人见解)
在有autowried的情况下
情况一:autowried(true)且autowried只有一个,返回此构造器即可(参数不在spring容器会报错)
情况二:一个或多个autowried(false)有参构造+无参构造+其他任何不带autowried的构造,返回autowried(false)有参构造+无参构造
因为spring不知道你加了autowried这个构造器有没有用,只能返回这个加上无参
情况三:autowried(true)+ autowried(true)抛异常 ,不可以用两个构造器
情况四:autowried(true)+ autowried(false)抛异常,这种情况我目前不太能理解,按我的逻辑返回autowried(true)就好了

经过上面方法决策后spring返回的构造器可能是null,可能有一个,可能有多个,spring还要进行一些列复杂操作,才能决策出最合适的构造器

接下来就是自动装配的逻辑了,在说这个之前,先理一下什么情况会进入自动装配逻辑,如下

		//第二次后置处理器 决策构造器
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		//ctors可能为null,可能有一个,可能有多个(存在autowired(false)的情况)
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			//四个条件分别是ctors不空,装配模式是构造器装配,bd有构造器参数,构造器参数args不空
			//ctors有一个:即只有(Autoiwired(true)这个)或者只有一个构造器(有参),spring要走下面逻辑自动给构造器装配参数
			//ctors有多个:即存在多个Autoiwired(false)或 一个或多个Autoiwired(false)+无参
			//这种情况比较复杂:他在自动装配逻辑里面还是要选择出最合适的那个,
			// 原则是选择参数最多的那个(并且参数都在spring容器里),如果没有一个这样的构造器,则使用无参构造器
			
			//第二个条件装配模式是构造器装配,这个我们得实现spring扩展接口BeanFactoryPostProcessor手动改成构造器装配
			//这样不管上面的ctors是什么,他都会走一遍自动装配逻辑
			
			//第三个条件 也可以实现BeanFactoryPostProcessor手动添加构造器参数
			//第四个条件可忽略(getBean传过来的就是null)
			
			//可以理解为自动装配逻辑
			return autowireConstructor(beanName, mbd, ctors, args);
		}
		//...省略
		//ctors==null并且使用手动装配模式NO,默认走无参
		return instantiateBean(beanName, mbd);//使用无参

下面的重点就是autowireConstructor这个方法了

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
			@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {

		BeanWrapperImpl bw = new BeanWrapperImpl();
		this.beanFactory.initBeanWrapper(bw);
		//最终使用的构造器
		Constructor<?> constructorToUse = null;
		//最终使用的构造器的参数封装的Holder对象
		ArgumentsHolder argsHolderToUse = null;
		//最终使用的构造器的参数
		Object[] argsToUse = null;
		//这个参数是从getBean传null过来的,大多数情况是null
		if (explicitArgs != null) {
			argsToUse = explicitArgs;
		}
		else {
			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);
			}
		}

		if (constructorToUse == null || argsToUse == null) {
			// Take specified constructors, if any.

			Constructor<?>[] candidates = chosenCtors;
			if (candidates == null) {
				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);
				}
			}

			//只有一个默认构造器
			if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
				Constructor<?> uniqueCandidate = candidates[0];
				if (uniqueCandidate.getParameterCount() == 0) {
					synchronized (mbd.constructorArgumentLock) {
						//给创建原型bean提供快捷方式,相当于把构造器缓存下来,下次直接用
						mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
						mbd.constructorArgumentsResolved = true;
						mbd.resolvedConstructorArguments = EMPTY_ARGS;
					}
					bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
					return bw;
				}
			}

			// Need to resolve the constructor.
			//是否需要自动装配,如果有构造器或者装配模式是构造器装配都要进行自动装配
			boolean autowiring = (chosenCtors != null ||
					mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
			ConstructorArgumentValues resolvedValues = null;

			int minNrOfArgs;//参数的最小个数,这个参数的作用是,当遍历构造器集合时发现某个构造器参数个数小于此值,直接continue
			if (explicitArgs != null) {
				//有构造器参数的话,参数最小个数赋值为这个长度,一般minNrOfArgs都是0
				minNrOfArgs = explicitArgs.length;
			}
			else {
				//我们很少给mbd设置ConstructorArgumentValues,故这里执行完minNrOfArgs还是0
				ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
				resolvedValues = new ConstructorArgumentValues();
				minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
			}
			//给构造器排序,排序规则:public>protected>private,相同访问权限下参数个数越多越排前面
			AutowireUtils.sortConstructors(candidates);
			//最小类型差异权重,此值越大差异越大,初始化为最大差异
			int minTypeDiffWeight = Integer.MAX_VALUE;
			//模棱两可的构造器集合,用于存储spring都不确定的构造器集合
			Set<Constructor<?>> ambiguousConstructors = null;
			//异常集合,例如,某个构造器参数不在spring容器中
			LinkedList<UnsatisfiedDependencyException> causes = null;
			//遍历构造器
			for (Constructor<?> candidate : candidates) {
				//构造器参数类型数组
				Class<?>[] paramTypes = candidate.getParameterTypes();
				//已经有最终构造器&&已经有最终构造器参数&&最终构造器参数长度>当前构造器参数长度(直接跳出循环,使用constructorToUse)
				if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
					break;
				}
				//当前构造器参数长度<构造器参数的最小个数,这种情况当前构造器肯定不合格,直接抛弃当前构造器
				if (paramTypes.length < minNrOfArgs) {
					continue;
				}
				//参数Holder
				ArgumentsHolder argsHolder;
				//上面new过了,不为null
				if (resolvedValues != null) {
					try {
						String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
						if (paramNames == null) {
							ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
							if (pnd != null) {
								//到这里就找到了当前构造器的参数的名字数组paramNames
								paramNames = pnd.getParameterNames(candidate);
							}
						}
						//这行代码极其复杂,我不打算往下深究了,但是我大概知道里面在做什么?
						//其实就是找出当前构造器的参数列表放到ArgumentsHolder对象中,但是这可能又会涉及到循环依赖的问题
						argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
								getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
						//到这里构造器参数就找到了
					}
					//如果构造器里面的参数不在spring容器,应该会进入catch
					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 LinkedList<>();
						}
						//加入异常集合
						causes.add(ex);
						continue;
					}
				}
				else {
					//进了else 说明explicitArgs不为null
					// Explicit arguments given -> arguments length must match exactly.
					if (paramTypes.length != explicitArgs.length) {
						//如果当前构造器参数长度不等于我们传的构造器参数长度,那么肯定可以抛弃当前构造器
						continue;
					}
					//直接用我们给的参数new一个ArgumentsHolder
					argsHolder = new ArgumentsHolder(explicitArgs);
				}
				//这是计算差异权重的代码
				//它会根据lenientConstructorResolution的值去选取一种算法
				//为true时选 getTypeDifferenceWeight(默认为true)
				//false选 getAssignabilityWeight
				int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
						argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
				//如果计算出来的权重<最小差异权重,那么说明我是更合适的,就要使用我这个构造器
				if (typeDiffWeight < minTypeDiffWeight) {
					//记录当前构造器及参数
					constructorToUse = candidate;
					argsHolderToUse = argsHolder;
					argsToUse = argsHolder.arguments;
					//更新最小差异权重
					minTypeDiffWeight = typeDiffWeight;
					//重置ambiguousConstructors为null
					ambiguousConstructors = null;
				}
				//如果已经有了最终的构造器可供使用&&当前构造器计算出来的权重==最小差异权重
				else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
					//这下spring就为难了,他把这两个构造器加到模糊集合了
					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)");
			}
			//如果有模糊构造器&&lenientConstructorResolution=false 抛异常,但是lenientConstructorResolution默认true
			//即不会抛异常,spring会拿constructorToUse去实例化bean
			//可是试一下这种情况,有两个构造器都只有一个参数,并且这个参数都在都在spring容器中,那么spring就不知道到底用哪个
			//这种情况下lenientConstructorResolution=true的意思是用第一个发现合格的构造器,然后会把这两个构造器加入模糊集合,不抛异常
			//我们也可以实现spring扩展接口手动修改lenientConstructorResolution=false,那么就会抛异常
			//有点像找老婆,找到两个一样漂亮的,有两种策略,一种是随便选一个(这里是选第一个),还一种是一个都不选,可以两个都要吗(手动滑稽)
			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 != null) {
				argsHolderToUse.storeCache(mbd, constructorToUse);
			}
		}

		Assert.state(argsToUse != null, "Unresolved constructor arguments");
		bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
		return bw;
	}

决策构造器到这里就算告一段落了,上面很多地方提到了BeanFactoryPostProcessoer接口,下面给一个例子

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		GenericBeanDefinition bd = (GenericBeanDefinition) beanFactory.getBeanDefinition("userService");
		bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);//构造器自动装配(如果设置自动注入,那么程序员手动添加的constrctorArgumentValues就不会生效了
		)
		bd.setLenientConstructorResolution(false);//false代表 当遇到两个权重一样的构造器抛异常,严于律己,不随便选
	}
}

第三次执行后置处理-处理@autowired,@Value和@resource

在说第三次后置处理器之前,我们先想一想spring决策完构造器new了空对象之后会做什么,如果是我肯定会去查找属性和方法,其中构造方法不需要再次解析(构造器已经被选出来了),但是查找出的属性和方法要不要进行DI和执行,答案是不要的,如果我们此时对属性进行填充,那么属性之间循环引用的问题就解决不了了,因此我们只需要先把加了Autowired和Resource的属性和方法缓存起来,待到我们把空对象提前暴露到早期单例池之后,在进行DI操作,这是解决循环依赖的关键。
下面我们来看看他是如何缓存属性和方法的

//第三次执行后置处理的入口
AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)
//遍历所有的bean后置处理器,把实现了MergedBeanDefinitionPostProcessor的拿出来执行postProcessMergedBeanDefinition方法
//这里我们只需要关注CommonAnnotationBeanPostProcessor(存储@Resource的属性和方法)和AutowiredAnnotationBeanPostProcessor(存储@Autowired和@Value的属性和方法)
//applyMergedBeanDefinitionPostProcessors:通过后置处理器应用合并bd(通过后置处理器从合并bd里面找出@Autowired和@Resource的属性和方法)
//合并bd 其实我之前一直不理解,还好有子路大神带着,感谢,抱拳!
//其实就是bd可能有父子关系,我们需要把子bd的属性覆盖掉父bd的属性,覆盖完之后的父bd就是RootBeanDefinition,这个就是一个MergedBeanDefinition(其实可以理解spring偷了懒,不过是很聪明的偷懒方式,她省了一个MergedBeanDefinition类的书写)
//这里我们直接从合并bd里面查找@Autowired,@Value和@Resource的属性和方法,那么什么时候做的合并bd,其实在refresh()里的invokeBeanFactoryProcessor里就已经合并了

下面我们只分析AutowiredAnnotationBeanPostProcessor,另一个几乎一样的

InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);//查找@Autowired的属性和方法
metadata.checkConfigMembers(beanDefinition);//意义不是很大
private InjectionMetadata findAutowiringMetadata(String beanName, Class<?> clazz, @Nullable PropertyValues pvs) {
		//DI元数据缓存的key
		String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
		//使用缓存提升效率
		InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
		//上面没有
		if (InjectionMetadata.needsRefresh(metadata, clazz)) {
			synchronized (this.injectionMetadataCache) {
				metadata = this.injectionMetadataCache.get(cacheKey);
				//双重检查
				if (InjectionMetadata.needsRefresh(metadata, clazz)) {
					//现在用不到这个if,之后DI可能用到
					if (metadata != null) {
						metadata.clear(pvs);
					}
					//查找@Autowired的属性和方法
					metadata = buildAutowiringMetadata(clazz);
					//添加缓存
					this.injectionMetadataCache.put(cacheKey, metadata);
				}
			}
		}
		return metadata;
	}
private InjectionMetadata buildAutowiringMetadata(final Class<?> clazz) {
		//为什么要定义两个list  elements  currElements ,定义一个直接add不行吗
		List<InjectionMetadata.InjectedElement> elements = new ArrayList<>();
		Class<?> targetClass = clazz;

		do {
			final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();
			//查找@Autowired属性
			//根绝targetClass查找出所有的field,遍历field数组,回调表达式
		ReflectionUtils.doWithLocalFields(targetClass, field -> {
				//判断属性是否有@Value或者@Autowired
				AnnotationAttributes ann = findAutowiredAnnotation(field);
				if (ann != null) {
					//static不可以加@Autowired,@Value
					if (Modifier.isStatic(field.getModifiers())) {
						if (logger.isInfoEnabled()) {
							logger.info("Autowired annotation is not supported on static fields: " + field);
						}
						return;
					}
					//@Autowired,@Value的Required值
					boolean required = determineRequiredStatus(ann);
					//添加进去  AutowiredFieldElement(field,boolean) extends 
					// InjectionMetadata.InjectedElement(Member member(member可以是方法,属性,构造器);boolean isField)
					currElements.add(new AutowiredFieldElement(field, required));
				}
			});
			//省略方法查找
			elements.addAll(0, currElements);
			//找父类
			targetClass = targetClass.getSuperclass();
		}
		//直到Object
		while (targetClass != null && targetClass != Object.class);

		return new InjectionMetadata(clazz, elements);
	}

@Nullable
	private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
		if (ao.getAnnotations().length > 0) {  // autowiring annotations have to be local
			//this.autowiredAnnotationTypes是下面代码加进去的,是Autowired.class,Value.class
			for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
				AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ao, type);
				if (attributes != null) {
					return attributes;
				}
			}
		}
		return null;
	}


public AutowiredAnnotationBeanPostProcessor() {
		this.autowiredAnnotationTypes.add(Autowired.class);
		this.autowiredAnnotationTypes.add(Value.class);
		try {
			this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
					ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
			logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
		}
		catch (ClassNotFoundException ex) {
			// JSR-330 API not available - simply skip.
		}
	}

到此的第三次后置处理器就差不多执行完了,属性和方法都存储在injectionMetadataCache缓存中

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值