Spring源码|Spring实例Bean的方法
liuian 2025-07-14 18:27 46 浏览
Spring实例Bean的方法,在
AbstractAutowireCapableBeanFactory中的
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
//解析Bean的类型,确认需要创建的bean实例的类可以实例化。
//如果没有设置通过Class.forName获取Bean类型
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 确保class不为空,并且访问权限是public
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方式创建Bean: 需要先有回调Bean
// 判断当前beanDefinition中是否包含实例供应器,此处相当于一个回调方法,利用回调方法来创建bean
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
//②FactoryMethod方式创建Bean: 需要在XML中配置factory-method
// 判断是否有工厂方法,如果存在,会尝试调用该Bean定义信息中的工厂方法来获取实例
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
//一个类可能有多个构造器,所以Spring得根据参数个数、类型确定需要调用的构造器,当多次构建同一个 bean 时就不需要重新判断应该使用那种方式构造Bean
boolean resolved = false;
//是否需要自动装配
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
// 因为判断过程会比较,所以spring会将解析、确定好的构造函数缓存到BeanDefinition中的resolvedConstructorOrFactoryMethod字段中。
// 在下次创建相同时直接从RootBeanDefinition中的属性resolvedConstructorOrFactoryMethod缓存的值获取,避免再次解析,导致循环依赖
if (mbd.resolvedConstructorOrFactoryMethod != null) {
//标识以及解析过class的构造器
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
// 有构造参数的或者工厂
if (resolved) {
//已经解析过class的构造器,使用已经解析好的构造器
if (autowireNecessary) {
//构造函数自动注入
return autowireConstructor(beanName, mbd, null, null);
}
else {
//使用默认构造器
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 从bean后置处理器中为自动装配寻找构造方法
// 以下情况符合其一即可进入
// 1、存在可选构造方法
// 2、自动装配模型为构造函数自动装配
// 3、给BeanDefinition中设置了构造参数值
// 4、有参与构造函数参数列表的参数
//一、确定构造参数
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
// 从bean后置处理器中为自动装配寻找构造方法, 有且仅有一个有参构造或者有且仅有@Autowired注解构造
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
// 构造函数自动注入
// 二、有参构造创建Bean
return autowireConstructor(beanName, mbd, ctors, null);
}
// No special handling: simply use no-arg constructor.
// 使用默认无参构造函数创建对象,如果没有无参构造且存在多个有参构造且没有@AutoWired注解构造,会报错
//三、无参构造创建Bean
return instantiateBean(beanName, mbd);
}
复制代码①:Supplier方式创建Bean:5、Spring源码之Supplier_蜗牛变犀牛的博客-CSDN博客
②:FactoryMethod方式创建Bean: 【Spring源码】8.IOC之创建bean对象之FactoryMethod - 简书 (jianshu.com)
③:自动装配类型
- int AUTOWIRE_NO = 0;//表示没有外部定义的自动装配
- int AUTOWIRE_BY_NAME = 1;//通过名称指示自动装配bean属性(适用于Bean所有属性的setter)
- int AUTOWIRE_BY_TYPE = 2;//通过类型指示自动装配bean属性(适用于Bean所有属性的setter)
- int AUTOWIRE_CONSTRUCTOR = 3;//构造函数
- int AUTOWIRE_AUTODETECT = 4;//通过bean类的内省确定适当的自动装配策略,在Spring3.0之后已经不再支持。
- String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";//用于没有代理的时候,也能强制返回实例
一、determineConstructorsFromBeanPostProcessors:确定构造参数
实现父类
SmartInstantiationAwareBeanPostProcessor后置处理器的
determineCandidateConstructors方法
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后置处理器确定构造函数
详情:juejin.cn/post/720467…
二、autowireConstructor:有参构造创建Bean
创建构造器解析器自动写入构造函数
protected BeanWrapper autowireConstructor(
String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
}
复制代码public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
@Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
//实例化BeanWrapper,是包装bean的容器
BeanWrapperImpl bw = new BeanWrapperImpl();
this.beanFactory.initBeanWrapper(bw);
Constructor<?> constructorToUse = null;
ArgumentsHolder argsHolderToUse = null;
Object[] argsToUse = null;
//如果getBean中传入的参数不为空,那么就使用传入的参数
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) {
//解析参数类型,比如将配置的String类型转换成int、boolean等类型
argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
}
}
//如果没有缓存,就需要先解析构造函数
if (constructorToUse == null || argsToUse == null) {
// Take specified constructors, if any.
// 如果传入的构造器数组不为空,就使用传入的构造器参数,否则通过反射获取class中定义的构造器
Constructor<?>[] candidates = chosenCtors;
if (candidates == null) {
Class<?> beanClass = mbd.getBeanClass();
try {
//通过反射获取class中定义的构造器
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);
}
}
//如果只有一个构造函数并且参数值为null,则直接使用无参构造器实例化
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;
}
}
// Need to resolve the constructor.
//如果构造器不会空或者需要构造器注入则需要自动装配
boolean autowiring = (chosenCtors != null ||
mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
ConstructorArgumentValues resolvedValues = null;
int minNrOfArgs;
if (explicitArgs != null) {
minNrOfArgs = explicitArgs.length;
}
else {
//获取构造参数值
ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
resolvedValues = new ConstructorArgumentValues();
//2.1 解析参数并返回最小参数个数
minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
}
//给构造函数排序,public构造函数优先、参数数量降序排序
AutowireUtils.sortConstructors(candidates);
int minTypeDiffWeight = Integer.MAX_VALUE;
Set<Constructor<?>> ambiguousConstructors = null;
LinkedList<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();
//需要解析的参数值不为空
if (resolvedValues != null) {
try {
//通过构造器上@ConstructorProperties注解获取参数名称
String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
//如果参数名称为空
if (paramNames == null) {
//获取参数名称解析器
ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
if (pnd != null) {
//获取参数名称
paramNames = pnd.getParameterNames(candidate);
}
}
//根据获取到的参数名和已经查到的构造参数和构造参数类型来创建用户创建构造器用的构造参数数组
//这个数组中包含了原始的参数列表和构造后的参数列表,用来对比用
//2.2 创建构造参数数组
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 LinkedList<>();
}
causes.add(ex);
continue;
}
}
else {
// Explicit arguments given -> arguments length must match exactly.
if (parameterCount != explicitArgs.length) {
continue;
}
argsHolder = new ArgumentsHolder(explicitArgs);
}
//如果是宽松的构造策略,则对比spring构造的参数数组的类型和获取到的构造器参数的参数类型进行对比,返回不同的个数
//如果是严格的构造策略,则检查能否将构造的参数数组赋值到构造器参数的参数列表中
int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
// Choose this constructor if it represents the closest match.
// 当前构造函数最为匹配的话,清空先前ambiguousConstructors列表
if (typeDiffWeight < minTypeDiffWeight) {
constructorToUse = candidate;
argsHolderToUse = argsHolder;
argsToUse = argsHolder.arguments;
minTypeDiffWeight = typeDiffWeight;
ambiguousConstructors = null;
}
//存在相同权重的构造器,将构造器添加到一个ambiguousConstructors列表变量中
//注意,这时候constructorToUse 指向的仍是第一个匹配的构造函数
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);
}
//缓存参数构造器,下次创建直接使用
//并设置constructorArgumentsResolved为true,表示已经解析过构造函数
if (explicitArgs == null && argsHolderToUse != null) {
argsHolderToUse.storeCache(mbd, constructorToUse);
}
}
Assert.state(argsToUse != null, "Unresolved constructor arguments");
//2.3 实例化Bean
bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
return bw;
}
复制代码2.1 resolveConstructorArguments:解析参数并返回最小参数个数
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
// 是否有定制的类型转换器,没有的话直接使用BeanWrapper进行类型转换
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
// 构造一个BeanDefinitionValueResolver,专门用于解析constructor-arg中的value属性,实际上还包括ref属性,内嵌bean标签等等
BeanDefinitionValueResolver valueResolver =
new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
// minNrOfArgs 记录执行方法要求的最小参数个数,一般情况下就是等于constructor-arg标签指定的参数数量
int minNrOfArgs = cargs.getArgumentCount();
for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
int index = entry.getKey();
if (index < 0) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Invalid constructor argument index: " + index);
}
// 假设A方法直接在配置文件中指定了index=3上要使用的参数,那么这个时候A方法至少需要4个参数
// 但是其余的3个参数可能不是通过constructor-arg标签指定的,而是直接自动注入进来的,那么在配置文件中我们就只配置了index=3上的参数,也就是说 int minNrOfArgs = cargs.getArgumentCount()=1,这个时候 index=3,minNrOfArgs=1, 所以 minNrOfArgs = 3+1
if (index + 1 > minNrOfArgs) {
minNrOfArgs = index + 1;
}
ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
// 如果已经转换过了,直接添加到resolvedValues集合中
if (valueHolder.isConverted()) {
resolvedValues.addIndexedArgumentValue(index, valueHolder);
}
else {
// 解析value/ref/内嵌bean标签等
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 将解析后的resolvedValue封装成一个新的ValueHolder,
// 并将其source设置为解析constructor-arg得到的那个ValueHolder,
// 后期会用到这个属性进行判断
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
resolvedValueHolder.setSource(valueHolder);
resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
}
}
// 对getGenericArgumentValues进行解析
for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
if (valueHolder.isConverted()) {
resolvedValues.addGenericArgumentValue(valueHolder);
}
else {
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
resolvedValue, valueHolder.getType(), valueHolder.getName());
resolvedValueHolder.setSource(valueHolder);
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
return minNrOfArgs;
}
复制代码2.2 createArgumentArray:创建构造参数数组
private ArgumentsHolder createArgumentArray(
String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {
TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
TypeConverter converter = (customConverter != null ? customConverter : bw);
ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
Class<?> paramType = paramTypes[paramIndex];
String paramName = (paramNames != null ? paramNames[paramIndex] : "");
// Try to find matching constructor argument value, either indexed or generic.
// 尝试找到匹配的构造函数参数值,无论是索引的还是泛型的。
ConstructorArgumentValues.ValueHolder valueHolder = null;
if (resolvedValues != null) {
valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
// If we couldn't find a direct match and are not supposed to autowire,
// let's try the next generic, untyped argument value as fallback:
// it could match after type conversion (for example, String -> int).
// 如果我们找不到直接匹配并且不应该自动装配,让我们尝试下一个通用的、无类型的参数值作为后备:它可以在类型转换后匹配(例如,String -> int)。
if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
}
}
if (valueHolder != null) {
// We found a potential match - let's give it a try.
// Do not consider the same value definition multiple times!
// 我们找到了一个潜在的匹配 - 让我们试一试。不要多次考虑相同的值定义!
usedValueHolders.add(valueHolder);
Object originalValue = valueHolder.getValue();
Object convertedValue;
if (valueHolder.isConverted()) {
convertedValue = valueHolder.getConvertedValue();
args.preparedArguments[paramIndex] = convertedValue;
}
else {
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
try {
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
}
catch (TypeMismatchException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Could not convert argument value of type [" +
ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
"] to required type [" + paramType.getName() + "]: " + ex.getMessage());
}
Object sourceHolder = valueHolder.getSource();
if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
args.resolveNecessary = true;
args.preparedArguments[paramIndex] = sourceValue;
}
}
args.arguments[paramIndex] = convertedValue;
args.rawArguments[paramIndex] = originalValue;
}
else {
// 这部分就是超出了参数定义,需要自动注入参数的处理
MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
// No explicit match found: we're either supposed to autowire or
// have to fail creating an argument array for the given constructor.
if (!autowiring) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
"Ambiguous argument values for parameter of type [" + paramType.getName() +
"] - did you specify the correct bean references as arguments?");
}
try {
Object autowiredArgument = resolveAutowiredArgument(
methodParam, beanName, autowiredBeanNames, converter, fallback);
args.rawArguments[paramIndex] = autowiredArgument;
args.arguments[paramIndex] = autowiredArgument;
args.preparedArguments[paramIndex] = autowiredArgumentMarker;
args.resolveNecessary = true;
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(
mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
}
}
}
for (String autowiredBeanName : autowiredBeanNames) {
this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
if (logger.isDebugEnabled()) {
logger.debug("Autowiring by type from bean name '" + beanName +
"' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
" to bean named '" + autowiredBeanName + "'");
}
}
return args;
}
复制代码2.3 instantiate:实例化Bean
private Object instantiate(String beanName, RootBeanDefinition mbd,
@Nullable Object factoryBean, Method factoryMethod, Object[] args) {
try {
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedAction<Object>) () ->
this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args),
this.beanFactory.getAccessControlContext());
}
else {
//四、使用实例化策略创建Bean
return this.beanFactory.getInstantiationStrategy().instantiate(
mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args);
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean instantiation via factory method failed", ex);
}
}
复制代码三、instantiateBean:无参构造创建Bean
无参构造
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
// 使用默认的实例化策略来实例化对象,默认为 CglibSubclassingInstantiationStrategy 实现,但是instantiate()方法只在SimpleInstantiationStrategy里有实现逻辑
//四、使用实例化策略创建Bean
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
}
复制代码四、使用实例化策略创建Bean
这里会进入
SimpleInstantiationStrategy的instantiate方法
@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
final Constructor<?> ctor, Object... args) {
//在将 XML 配置解析成 BeanDefinition 的时候,bean标签的lookup-method和replaced-method会被分别解析成 LookupOverride 和 ReplaceOverride 对象
//添加到 BeanDefinition 的methodOverrides成员变量中
//如果没有配置就会走当前这个流程
if (!bd.hasMethodOverrides()) {
if (System.getSecurityManager() != null) {
// use own privileged to change accessibility (when security is on)
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(ctor);
return null;
});
}
//4.1、反射创建Bean
return BeanUtils.instantiateClass(ctor, args);
}
else {
//如果方法被覆盖,通过Cglib实现代理类
//4.2、Cglib创建代理类
return instantiateWithMethodInjection(bd, beanName, owner, ctor, args);
}
}
复制代码4.1、反射创建Bean
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
//设置访问权限
ReflectionUtils.makeAccessible(ctor);
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
//初始化参数
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
return ctor.newInstance(argsWithDefaultValues);
}
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
}
复制代码4.2、Cglib创建代理类
@Override
protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner,
@Nullable Constructor<?> ctor, Object... args) {
// Must generate CGLIB subclass...
return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
}
复制代码创建Cglib代理类
public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
//创建Cglib增强子类
Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
Object instance;
if (ctor == null) {
//4.1 反射创建Bean
instance = BeanUtils.instantiateClass(subclass);
}
else {
try {
//反射创建Bean
Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
instance = enhancedSubclassConstructor.newInstance(args);
}
catch (Exception ex) {
throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
}
}
// SPR-10785: set callbacks directly on the instance instead of in the
// enhanced class (via the Enhancer) in order to avoid memory leaks.
Factory factory = (Factory) instance;
factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
return instance;
}
复制代码总结
自动构造:autowireConstructor
- 将所有的候选构造函数排序,排序规则[第一排序规则: public方法优先,第二排序规则:参数数量降序]
- 设置一个算法,输入构造函数,输出一个整数
- 判断构造方法能否完成依赖注入,不能跳过该构造函数
- 算法输出的最小值则作为被选中的构造函数
- 通过选中的构造函数完成对象实例化
- 算法根据mbd.isLenientConstructorResolution(默认宽松模式)区分严格模式和宽松模式,不同的模式有不同计算方式
相关推荐
- 万能bt搜索引擎网站(bt万能搜索破解版)
-
最好用最全面的的磁力搜索引擎是磁力熊,因为它是一个内容丰富、还是功能最为强大的一个磁力搜索网站,通过它不仅仅可以搜索磁力熊磁力熊,是一个内容丰富、功能最为强大的一个磁力搜索网站,通过它不仅仅可以搜索...
- 苹果id注册官网登录(appleid官网注册账号)
-
浏览器访问申请AppleID官网注册 1、在浏览器地址栏上面输入:“https://appleid.apple.com/cn”,进入申请AppleID官网界面,点击下面的“创建AppleID...
- 苹果笔记本怎么下载windows系统
-
方法一:使用BootCamp方法二:使用虚拟机方法三:使用Wine简介BootCamp是苹果电脑自带的一个软件,可以帮助用户在Mac上安装Windows操作系统。虚拟机则是运行在Mac上的一个软件...
- 华硕电脑激活码(华硕电脑windows激活码在哪里)
-
你所说的应该是系统激活密钥吧华硕OEM密钥就行!HomePremium(家庭高级版):27GBM-Y4QQC-JKHXW-D9W83-FJQKDUltimate(旗舰版):6K2KY-BF...
- wifi如何防止别人蹭网(wifi如何防止别人蹭网呢)
-
防止WIFI被蹭网的方法1、家庭的wifi信号,一般是通过设置无线路由器发射出来。在设置无线路由器时,一定要注意设置无线密码的安全强度。最好含有大小写字母加数字的组合,不要设置连续数字,比如“1234...
- 无线ap安装示意图(无线ap如何安装方法)
-
商用无线ap安装完成后连接ap应用添加wifi网络信号将无线网卡插入电脑USBWindows7/8系统下,网卡安装成功后直接进行软件安装...2.继续安装类型,推荐保持默认选择,点击“下一步”继续安装...
- miui官网开发版下载(小米miui开发版下载)
-
你好,miui12开发版下载方式如下1打开浏览器,登录小米Rom官网,2进去之后搜索自己的手机型号,3点击进入就可以看到所有发布过的miui版本4点击想要的12版本下载即可。现在的MIUI开发版需要申...
-
- 惠普台式机进入bios设置u盘启动
-
设置u盘启动的步骤如下:1、首先,将u盘插入hp台式机的USB接口处。2、开机快速断续的按F10键进入BIOS设置界面。3、将光标移到【BootDevicePriority】选项按回车键进入。4、选择【HDDGroupBootPr...
-
2026-01-15 00:37 liuian
- 云手机免费版无限挂机怎么用
-
1、登陆后,如果需要挂网页游戏,点击服务器的左下角,找到IE浏览器,然后打开网页游戏,登陆你的账号就行了,不要关闭IE浏览器,你的网页游戏就会24小时挂在云服务器上面。2、如果想要挂机,打开IE浏览器...
- 上海最近3天疫情情况(上海近几天的新冠疫情情况)
-
根据国家卫健委的每天疫情通报及上海市的疫情通报,上海没有一个区属中高风险地区,所以从上海任何一个区返乡都不需要隔离14天。上海这么大的城市,每天人来人往的Ill流不息,能继续做到区级地区没有中高级风险...
- windows media player怎么下载
-
方法如下:在安装WMP11时只是把C:\DocumentsandSettings\AllUsers\ApplicationData\WindowsGenuineAdvantage\data...
- during(during用法)
-
during用来表示一段时间,其意义大致相当于in的用法。一般来说,凡是能用in的地方,也可以用during.例如:Hecametoseemeduringmyabsence.Don’t...
- 深圳电脑城在哪里(深圳电脑卖场)
-
龙岗:世纪电脑城,平湖电脑城,京科电脑城坪山新区:坪山电脑城龙华:观澜电脑城,大浪电脑城,宏华电脑城,龙华电子城宝安区:赛格电子城,宝安电子城,丰明电脑城,沙井电子城龙岗中心区那边有两个电子城,...
- 电脑上怎么清理c盘垃圾(电脑里怎么清理c盘的东西)
-
C:\ProgramFiles\WindowsApps(隐藏文件夹)。打开“此电脑”,点击“查看”,勾选“隐藏的项目”,即可查看隐藏文件。为保证文件安全,此文件夹需要获取权限才能操作。获取方式...
- 手机哪个杀毒软件最好用
-
杀毒软件我有用过好几种用过之觉得体验感及安全性来说人喜欢推荐腾讯手机管家功能比较全面监控流量、查杀病毒、保护隐私等等界面也比较漂亮重点还要定期扫描同时也要轻易点开别人发链接之类软件有提示危险绝对要点开...
- 一周热门
-
-
飞牛OS入门安装遇到问题,如何解决?
-
如何在 iPhone 和 Android 上恢复已删除的抖音消息
-
Boost高性能并发无锁队列指南:boost::lockfree::queue
-
大模型手册: 保姆级用CherryStudio知识库
-
用什么工具在Win中查看8G大的log文件?
-
如何在 Windows 10 或 11 上通过命令行安装 Node.js 和 NPM
-
威联通NAS安装阿里云盘WebDAV服务并添加到Infuse
-
Trae IDE 如何与 GitHub 无缝对接?
-
idea插件之maven search(工欲善其事,必先利其器)
-
如何修改图片拍摄日期?快速修改图片拍摄日期的6种方法
-
- 最近发表
- 标签列表
-
- python判断字典是否为空 (50)
- crontab每周一执行 (48)
- aes和des区别 (43)
- bash脚本和shell脚本的区别 (35)
- canvas库 (33)
- dataframe筛选满足条件的行 (35)
- gitlab日志 (33)
- lua xpcall (36)
- blob转json (33)
- python判断是否在列表中 (34)
- python html转pdf (36)
- 安装指定版本npm (37)
- idea搜索jar包内容 (33)
- css鼠标悬停出现隐藏的文字 (34)
- linux nacos启动命令 (33)
- gitlab 日志 (36)
- adb pull (37)
- python判断元素在不在列表里 (34)
- python 字典删除元素 (34)
- vscode切换git分支 (35)
- python bytes转16进制 (35)
- grep前后几行 (34)
- hashmap转list (35)
- c++ 字符串查找 (35)
- mysql刷新权限 (34)
