1、createBeanInstance方法讲解
摘要:
本文主要分析了Spring框架中createBeanInstance和determineCandidateConstructors两个核心方法的实现逻辑。createBeanInstance负责Bean实例化,处理了Supplier、工厂方法、构造方法注入等多种实例化方式,并采用缓存机制优化性能。determineCandidateConstructors方法通过注解处理和缓存检查确定候选构造方法,支持@Autowired和@Lookup等注解,实现了方法级别依赖注入。两个方法共同构成了Spring容器创建Bean实例的核心流程,体现了Spring在依赖注入和性能优化方面的设计思想。
1、全路径是
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
流程图:

2、源码方法讲解
c
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//1.解析BeanClass
Class<?> beanClass = resolveBeanClass(mbd, beanName);
//2.检查访问权限
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());
}
}
resolveBeanClass():从BeanDefiniton中解析出实际的class对象
Supplier机制:通过编程式API提供的Bean实例生成器,优先级最高。
c
// Supplier检查(最高优先级)
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 工厂检查方法
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
工厂方法:对应@Bean注解的方法或XML配置的factory-method
c
// 构造方法缓存检查(性能优化)
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// resolvedConstructorOrFactoryMethod 缓存的构造方法或工厂方法
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
// constructorArgumentsResolved 标识构造方法参数是否已解析
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
c
if (resolved) {
// autowireNecessary=true 需要构造方法注入
if (autowireNecessary) {
// 方法内会拿到缓存好的构造方法的入参
return autowireConstructor(beanName, mbd, null, null);
}
// 需要无参构造,直接进行实例化
else {
return instantiateBean(beanName, mbd);
}
}
构造方法注入的判断条件:
1、后置处理器返回了候选构造方法(如@Autowired标注的构造方法)
2、BeanDefinition的自动装配模式是
3、BeanDefinition中制定了构造方法参数值AUTOWIRE_CONSTRUCTOR
4、getBean()时传入了构造参数
c
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 不匹配以上情况,则直接使用无参构造方法
return instantiateBean(beanName, mbd);
2、determineCandidateConstructors方法讲解
1、方法流程图:

2、相关源码讲解
c
if (!this.lookupMethodsChecked.contains(beanName)) {
if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {
try {
Class<?> targetClass = beanClass;
do {
// 遍历targetClass中的method,查看是否写了@Lookup方法
ReflectionUtils.doWithLocalMethods(targetClass, method -> {
Lookup lookup = method.getAnnotation(Lookup.class);
if (lookup != null) {
Assert.state(this.beanFactory != null, "No BeanFactory available");
// 将当前method封装成LookupOverride并设置到RootBeanDefinition的methodOverrides中
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);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);
}
}
this.lookupMethodsChecked.add(beanName);
}
@Lookup 注解作用:实现方法级别的依赖注入 ,主要用于原型bean注入到单例bean里面
缓存机制:lookupMethodsChecked集合记录已处理过的bean,避免重复处理
1)缓存检查双重锁定
c
// 1.第一次检查无锁,减少同步开销
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// 2.确保只有一个线程执行解析逻辑
synchronized (this.candidateConstructorsCache) {
// 3.有锁,再次检查防止多个线程通过第一次检查
candidateConstructors = this.candidateConstructorsCache.get(beanClass);
if (candidateConstructors == null) {
// 构造方法解析逻辑...
}
}
}
2) 变量初始化
c
// 用来记录required为true的构造方法,一个类中只能有一个required为true的构造方法,多个会报错
Constructor<?> requiredConstructor = null;
// 记录默认无参的构造方法
Constructor<?> defaultConstructor = null;
// kotlin主构造器
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);
int nonSyntheticConstructors = 0;
3) @Autowired构造方法处理
c
// 构造方法加了 @Autowired注解
if (ann != null) {
// 整个类中如果有一个required为true的构造方法,不能有其他的加了@Autowired的构造方法,否则报错
if (requiredConstructor != null) {
throw new BeanCreationException(beanName,
"Invalid autowire-marked constructor: " + candidate +
". Found constructor with 'required' Autowired annotation already: " +
requiredConstructor);
}
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);
}
// 记录唯一一个required为true的构造方法
requiredConstructor = candidate;
}
// 记录所有加了@Autowired注解的构造方法,包括required为true或者false的
candidates.add(candidate);
}
@Autowired注解规则:
required = true:一个类中最多只有一个
required = false:可以有多个
候选构造方法决策逻辑
c
if (!candidates.isEmpty()) {
// 如果不存在一个required为true的构造方法,
// 则所有required为false的构造方法和无参构造方法都是合格的
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));
}
}
// 如果只存在一个required为true的构造方法,那就只有这一个是合格的
candidateConstructors = candidates.toArray(new Constructor<?>[0]);
}
决策逻辑:
- 情况1:存在@Autowired构造方法
- 有requiredConstructor:只使用该构造方法
- 无requiredConstructor:添加无参构造方法作为备选
- 情况2:无@Autowired注解,只有一个有参构造方法 → 使用该构造方法
- 情况3:无@Autowired注解,多个构造方法 → 返回空数组
喜欢我的文章记得点个在看,或者点赞,持续更新中ing...