Spring 5.x Source trip twenty-three getBean Detailed constructor Nine instantiated

Spring 5.x Source trip twenty-three Detailed getBean looking constructor Nine

determineConstructorsFromBeanPostProcessors

Speaking in front of the instantiation process plant, can now speak normal constructor instantiated, will first processor, configured to identify a suitable method:

@Nullable
	protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {

		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
						return ctors;
					}
				}
			}
		}
		return null;
	}

AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors

The main processor is done, start checking Lookupnotes, then processing method of adding coverage. Mainly behind constructor acquisition, first obtain the cache, and if not, then you get all the constructors, then each constructor have to traverse to get notes, if it is empty, then judgment is not a proxy class, yes, then get the parent class, which is our own definition of class, get notes again. If annotations exist, to see Autowiredthe requiredproperty, if there are multiple trueor one is true, the other is falsewill be an error, because he can not know with what, if all falsethat is possible. If only one false, a warning will be reported. If you have a Autowiredcomment, you constructor annotated priority, if not, only a constructor parameter and has priority, then there is a priority constructor, with Kotlinrelevant, so basically not a priority, then the rest is a default constructor a. Note If you have multiple constructors have parameters in fact he does not know what to use, when instantiated will find default constructor, but did not find, an exception will be reported.

@Override
	@Nullable
	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName)
			throws BeanCreationException {

		// 查找lookup
		if (!this.lookupMethodsChecked.contains(beanName)) {
			if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
				try {
					Class<?> targetClass = beanClass;
					do {//遍历当前类以及所有父类,找出Lookup注解的方法进行处理
						ReflectionUtils.doWithLocalMethods(targetClass, method -> {
							Lookup lookup = method.getAnnotation(Lookup.class);
							if (lookup != null) {
								Assert.state(this.beanFactory != null, "No BeanFactory available");
								LookupOverride override = new LookupOverride(method, lookup.value());
								try {
									RootBeanDefinition mbd = (RootBeanDefinition)
											this.beanFactory.getMergedBeanDefinition(beanName);
									mbd.getMethodOverrides().addOverride(override);
								}
								catch (NoSuchBeanDefinitionException ex) {
									throw new BeanCreationException(beanName,
											"Cannot apply @Lookup to beans without corresponding bean definition");
								}
							}
						});
						targetClass = targetClass.getSuperclass();
					}
					while (targetClass != null && targetClass != Object.class);//遍历父类,直到Object

				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
				}
			}
			this.lookupMethodsChecked.add(beanName);//已经检查过
		}

		//先检查一遍缓存
		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;//默认构造方法
					Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);//优先的构造方法,Kotlin的类才有,一般都是空
					int nonSyntheticConstructors = 0;
					for (Constructor<?> candidate : rawCandidates) {
						if (!candidate.isSynthetic()) {//非合成的方法
							nonSyntheticConstructors++;
						}
						else if (primaryConstructor != null) {
							continue;
						}
						MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);//寻找Autowired和value的注解
						if (ann == null) {
							Class<?> userClass = ClassUtils.getUserClass(beanClass);
							if (userClass != beanClass) {//如果是有代理的,找到被代理类
								try {
									Constructor<?> superCtor =//获取构造方法
											userClass.getDeclaredConstructor(candidate.getParameterTypes());
									ann = findAutowiredAnnotation(superCtor);//继续寻找Autowired和value的注解
								}
								catch (NoSuchMethodException ex) {
									// Simply proceed, no equivalent superclass constructor found...
								}
							}
						}
						if (ann != null) {
							if (requiredConstructor != null) {//有两个Autowired注解,冲突了
								throw new BeanCreationException(beanName,
										"Invalid autowire-marked constructor: " + candidate +
										". Found constructor with 'required' Autowired annotation already: " +
										requiredConstructor);
							}
							boolean required = determineRequiredStatus(ann);//是否需要,默认是true
							if (required) {
								if (!candidates.isEmpty()) {//如果已经有required=false了,又来了一个required=true的方法就报异常了,这样两个可能就不知道用哪个了
									throw new BeanCreationException(beanName,
											"Invalid autowire-marked constructors: " + candidates +
											". Found constructor with 'required' Autowired annotation: " +
											candidate);
								}
								requiredConstructor = candidate;
							}
							candidates.add(candidate);//加入集合
						}
						else if (candidate.getParameterCount() == 0) {//是无参构造方法
							defaultConstructor = candidate;
						}
					}
					if (!candidates.isEmpty()) {//如果候选不为空,基本就是有Autowired注解的,转换成数组直接返回
						// Add default constructor to list of optional constructors, as fallback.
						if (requiredConstructor == null) {
							if (defaultConstructor != null) {//添加默认构造函数
								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]};//只有一个函数且有参数
					}
					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 {//大于2个没注解的构造方法就不知道要用什么了,所以就返回null
						candidateConstructors = new Constructor<?>[0];
					}
					this.candidateConstructorsCache.put(beanClass, candidateConstructors);
				}
			}
		}
		return (candidateConstructors.length > 0 ? candidateConstructors : null);
	}

Summary The following is:

  • If there is more Autowired, requiredthere true, with or without a default constructor, an exception will be reported.
  • If only one Autowired, requiredShi false, no default constructor, a warning will be reported.
  • If you do not Autowired annotation defines 2one or more parameters of the constructor has no constructor with no arguments, it will error.
  • Other cases can be, but to have a Autowiredconstructor priority, and is the default constructor.

If the constructor parameter is present and, it will invoke autowireConstructorthe automatic assembling, if there is no substantially constructor with no arguments, unless there is Kotlinprovided a method configured priority. And behind in terms of automated assembly default constructor how it is instantiated.

Well, here today, we hope to help study and understand, do not spray the Great God see, understand only their own learning, limited capacity, please excuse.

Published 235 original articles · won praise 74 · views 30000 +

Guess you like

Origin blog.csdn.net/wangwei19871103/article/details/105103688