spring源码(bean的实例化)——determineCandidateConstructors篇
引言
determineCandidateConstructors——spring创建实例无法避免的一个方法,大家一起学习,让我们对spring创建bean的过程更加深刻
代码
@Nullable
public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, final String beanName) throws BeanCreationException {
//在开始处理构造函数之前,先检查beanClass中是否存在@Lookup注解的方法。如果有,可能会影响构造函数的选择。
this.checkLookupMethods(beanClass, beanName);
//首先尝试从缓存candidateConstructorsCache中获取该beanClass的候选构造函数。
//如果缓存中不存在,则进入同步块进一步处理。
Constructor<?>[] candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
//使用同步块确保线程安全,避免多个线程同时处理同一个beanClass的构造函数。
synchronized(this.candidateConstructorsCache) {
candidateConstructors = (Constructor[])this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
Constructor<?>[] rawCandidates;
try {
//通过反射获取beanClass中所有声明的构造函数
rawCandidates = beanClass.getDeclaredConstructors();
} catch (Throwable ex) {
throw new BeanCreationException(beanName, "Resolution of declared constructors on bean Class [" + beanClass.getName() + "] from ClassLoader [" + String.valueOf(beanClass.getClassLoader()) + "] failed", ex);
}
/**
初始化变量:
candidates: 存储候选构造函数的列表。
requiredConstructor: 标记带有@Autowired(required=true)注解的构造函数。
defaultConstructor: 标记无参构造函数。
primaryConstructor: 通过BeanUtils.findPrimaryConstructor找到的主构造函数。
nonSyntheticConstructors: 统计非合成构造函数的数量。**/
List<Constructor<?>> candidates = new ArrayList(rawCandidates.length);
Constructor<?> requiredConstructor = null;
Constructor<?> defaultConstructor = null;
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
/**
过滤合成构造函数: 合成构造函数(如内部类的构造函数)通常不需要处理。
查找@Autowired注解: 通过findAutowiredAnnotation方法检查构造函数是否带有@Autowired注解。
处理无参构造函数: 如果构造函数没有参数,则标记为defaultConstructor。**/
for(Constructor<?> candidate : rawCandidates) {
if (!candidate.isSynthetic()) {
++nonSyntheticConstructors;
} else if (primaryConstructor != null) {
continue;
}
MergedAnnotation<?> ann = this.findAutowiredAnnotation(candidate);
if (ann == null) {
Class<?> userClass = ClassUtils.getUserClass(beanClass);
if (userClass != beanClass) {
try {
Constructor<?> superCtor = userClass.getDeclaredConstructor(candidate.getParameterTypes());
ann = this.findAutowiredAnnotation(superCtor);
} catch (NoSuchMethodException var19) {
}
}
}
if (ann != null) {
if (requiredConstructor != null) {
String var23 = String.valueOf(candidate);
throw new BeanCreationException(beanName, "Invalid autowire-marked constructor: " + var23 + ". Found constructor with 'required' Autowired annotation already: " + String.valueOf(requiredConstructor));
}
boolean required = this.determineRequiredStatus(ann);
if (required) {
if (!candidates.isEmpty()) {
String var10003 = String.valueOf(candidates);
throw new BeanCreationException(beanName, "Invalid autowire-marked constructors: " + var10003 + ". Found constructor with 'required' Autowired annotation: " + String.valueOf(candidate));
}
requiredConstructor = candidate;
}
candidates.add(candidate);
} else if (candidate.getParameterCount() == 0) {
defaultConstructor = candidate;
}
}
/**优先选择带有@Autowired注解的构造函数。
如果没有合适的构造函数,则根据以下规则选择:
如果只有一个构造函数且带参数,则选择该构造函数。
如果有两个非合成构造函数(主构造函数和无参构造函数),则选择它们。
如果只有一个非合成构造函数(主构造函数),则选择它。
否则,返回空数组。**/
if (!candidates.isEmpty()) {
if (requiredConstructor == null) {
if (defaultConstructor != null) {
candidates.add(defaultConstructor);
} else if (candidates.size() == 1 && this.logger.isInfoEnabled()) {
this.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: " + String.valueOf(candidates.get(0)));
}
}
candidateConstructors = (Constructor[])candidates.toArray(EMPTY_CONSTRUCTOR_ARRAY);
} 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 {
candidateConstructors = EMPTY_CONSTRUCTOR_ARRAY;
}
//将最终确定的候选构造函数存入缓存,避免重复计算。
this.candidateConstructorsCache.put(beanClass, candidateConstructors);
}
}
}
return candidateConstructors.length > 0 ? candidateConstructors : null;
}
讲解
总的来说就是根据你创建的bean,判断是否为有参构造,是否为无参构造,是否通过Autowired进行了注解,这是我的理解,大佬们也可以多多补充一下,因为这也是我在背八股文时一直背不到这个才请教大佬,大佬叫我看源码我理解的
但是还是不怎么理解,只是把这个方法能够理解表层了