zl程序教程

您现在的位置是:首页 >  其他

当前栏目

Spring源码 – bean创建的生命周期之实例化-createBeanInstance(Spring Framework 5.3.7-SNAPSHO)

2023-02-26 10:18:17 时间

构造函数的选取逻辑

  1. 在doCreateBean中给属性赋值之前,调用createBeanInstance
// Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) {     // factoryBeanInstanceCache存储的是:beanName对应的FactoryBean实例对象     instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) {     // 根据构造函数实例化,创建Bean实例     instanceWrapper = createBeanInstance(beanName, mbd, args); }
  1. 进入createBeanInstance,整体逻辑的描述如源码中注释,构造函数的返回主要是通过自动注入autowireConstructor和使用默认构造函数instantiateBean,重点关注determineConstructorsFromBeanPostProcessors,它里面的逻辑主要是调用SmartInstantiationAwareBeanPostProcessor类型的后置处理器,determineCandidateConstructors方法返回候选的构造器集合,源码接着下一步
// Make sure bean class is actually resolved at this point. Class<?> beanClass = resolveBeanClass(mbd, beanName);  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()); }  // Spring5新增的判断逻辑 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) {     return obtainFromSupplier(instanceSupplier, beanName); }  if (mbd.getFactoryMethodName() != null) {     return instantiateUsingFactoryMethod(beanName, mbd, args); }  // Shortcut when re-creating the same bean... // 解析构造函数,根据参数和类型判断使用哪个构造函数进行实例化 boolean resolved = false; boolean autowireNecessary = false; if (args == null) {     synchronized (mbd.constructorArgumentLock) {         if (mbd.resolvedConstructorOrFactoryMethod != null) {             resolved = true;             autowireNecessary = mbd.constructorArgumentsResolved;         }     } } // 如果已经解析,则直接从从缓存中获取 if (resolved) {     if (autowireNecessary) {         // 构造函数自动注入         return autowireConstructor(beanName, mbd, null, null);     } else {         // 使用默认构造函数构造         return instantiateBean(beanName, mbd);     } }  // Candidate constructors for autowiring? // 根据参数解析构造函数 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||         mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {     return autowireConstructor(beanName, mbd, ctors, args); }  // Spring5新增 // Preferred constructors for default construction? ctors = mbd.getPreferredConstructors(); if (ctors != null) {     return autowireConstructor(beanName, mbd, ctors, null); }  // No special handling: simply use no-arg constructor. // 使用默认构造函数构造 return instantiateBean(beanName, mbd);
  1. determineConstructorsFromBeanPostProcessors的源码
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {     for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {         Constructor<?>[] ctors = bp.determineCandidateConstructors(beanClass, beanName);         if (ctors != null) {             return ctors;         }     } } return null;
  1. AutowiredAnnotationBeanPostProcessor的determineCandidateConstructors方法,分为两步:[email protected];二、执行真正的构造器选择逻辑
// Let's check for lookup methods here... if (!this.lookupMethodsChecked.contains(beanName)) {     if (AnnotationUtils.isCandidateClass(beanClass, Lookup.class)) {         try {             Class<?> targetClass = beanClass;             do {                 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);          }         catch (IllegalStateException ex) {             throw new BeanCreationException(beanName, "Lookup method resolution failed", ex);         }     }     this.lookupMethodsChecked.add(beanName); }  // Quick check on the concurrent map first, with minimal locking. 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);             // 存放required=true的构造器             Constructor<?> requiredConstructor = null;             // 存放默认的构造器             Constructor<?> defaultConstructor = null;             Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);             int nonSyntheticConstructors = 0;             for (Constructor<?> candidate : rawCandidates) {                 if (!candidate.isSynthetic()) {                     nonSyntheticConstructors++;                 }                 else if (primaryConstructor != null) {                     continue;                 }                 // 查找当前构造器上面的注解                 MergedAnnotation<?> ann = findAutowiredAnnotation(candidate);                 // 没有注解                 if (ann == null) {                     Class<?> userClass = ClassUtils.getUserClass(beanClass);                     if (userClass != beanClass) {                         try {                             Constructor<?> superCtor =                                     userClass.getDeclaredConstructor(candidate.getParameterTypes());                             ann = findAutowiredAnnotation(superCtor);                         }                         catch (NoSuchMethodException ex) {                             // Simply proceed, no equivalent superclass constructor found...                         }                     }                 }                 // 有注解                 if (ann != null) {                     if (requiredConstructor != null) {                         // 说明已经存在required=true的构造器,抛异常                         throw new BeanCreationException(beanName,                                 "Invalid autowire-marked constructor: " + candidate +                                 ". Found constructor with 'required' Autowired annotation already: " +                                 requiredConstructor);                     }                     // 判断注解的属性required的值                     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);                         }                         // 把当前构造器存入requiredConstructor                         requiredConstructor = candidate;                     }                     candidates.add(candidate);                 }                 else if (candidate.getParameterCount() == 0) {                     // 如果当前构造器上面没有注解,并且参数个数为0,则存入默认构造器defaultConstructor                     defaultConstructor = candidate;                 }             }             if (!candidates.isEmpty()) {                 // Add default constructor to list of optional constructors, as fallback.                 // 没有required=true的构造器                 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) {                 // 如果适用的构造器只有1个,并且参数的个数大于0,则直接选用该构造器                 candidateConstructors = new Constructor<?>[] {rawCandidates[0]};             }             else if (nonSyntheticConstructors == 2 && primaryConstructor != null &&                     defaultConstructor != null && !primaryConstructor.equals(defaultConstructor)) {                 // 如果有2个构造器,并且默认的构造器不为空                 candidateConstructors = new Constructor<?>[] {primaryConstructor, defaultConstructor};             }             else if (nonSyntheticConstructors == 1 && primaryConstructor != null) {                 candidateConstructors = new Constructor<?>[] {primaryConstructor};             }             else {                 // 上面都不符合,返回空                 candidateConstructors = new Constructor<?>[0];             }             // 存入缓存,方便下一次获取             this.candidateConstructorsCache.put(beanClass, candidateConstructors);         }     } } // 结果不为空则直接返回,否则返回null return (candidateConstructors.length > 0 ? candidateConstructors : null); 
  1. 对上述第二步的流程做一个说明,

    • 首先对候选的构造器结果candidateConstructors作双重检查,以防多线程并发带来的问题;
    • 接着通过Class<?>反射获取所有声明的构造函数
    • 对上述通过反射获取的构造函数循环遍历

      (福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>

      • 对于每个构造器,[email protected],@Value,javax.inject.Inject等注解
      • 如果当前构造器上面没有注解,并且参数个数为0,则存入默认构造器defaultConstructor
      • 如果有注解,并且存放required=true的构造器不为空,则抛异常;如果为空,判断注解的属性required的值,把当前构造器存入requiredConstructor
    • 结果判断:没有required=true的构造器,并且默认构造器不为空,则存入最终适用的构造器
    • 如果适用的构造器只有1个,并且参数的个数大于0,则直接选用该构造器
    • 如果有2个构造器,并且默认的构造器不为空,也存入最终适用的构造器
    • 如果构造器只有一个,并且primaryConstructor不为空,则直接存入结果构造器集合
    • 以上都不符合,则返回空,在推出该函数后,如果为空,则系统最后会采用默认的构造函数
    • 把结果存入缓存,便于下一次直接获取
  2. 举例说明:
  • [email protected],且required默认,即:值为true,则Spring会采用被注解标注的那一个
@Autowired public Color(Blue blue, Cyan cyan) {     this.blue = blue;     this.cyan = cyan; }  public Color(Cyan cyan) {     this.cyan = cyan; }  // 默认构造函数 public Color() {}
  • [email protected],两个required都是true,Spring会抛异常
// ----------------------------示例代码---------------------------- @Autowired public Color(Blue blue, Cyan cyan) {     this.blue = blue;     this.cyan = cyan; }  @Autowired public Color(Cyan cyan) {     this.cyan = cyan; }  // 默认构造函数 public Color() {} }
  • [email protected],一个required是true,一个required是false
  1. 情形(一),抛异常:“Found constructor with ‘required’ Autowired annotation already XXX”
// ----------------------------示例代码---------------------------- @Autowired(required = false) public Color(Blue blue, Cyan cyan) {     this.blue = blue;     this.cyan = cyan; }  @Autowired public Color(Cyan cyan) {     this.cyan = cyan; }  // 默认构造函数 public Color() {} 
  1. 情形(二),也会抛异常:“Found constructor with ‘required’ Autowired annotation:”
// ----------------------------示例代码---------------------------- @Autowired public Color(Blue blue, Cyan cyan) {     this.blue = blue;     this.cyan = cyan; }  @Autowired(required = false) public Color(Cyan cyan) {     this.cyan = cyan; }  // 默认构造函数 public Color() {}
  • [email protected],两个required都是false,Spring经过处理之后会根据选取的原则选择一个构造函数,结果candidates会存入下面示例代码中所有的构造函数,返回出去之后,外层函数会调用autowireConstructor,选择一个构造函数,源码分析如下:
// ----------------------------示例代码---------------------------- @Autowired(required = false) public Color(Blue blue, Cyan cyan) {     this.blue = blue;     this.cyan = cyan; }  @Autowired(required = false) public Color(Cyan cyan) {     this.cyan = cyan; }  // 默认构造函数 public Color() {}  // ---------------上述情形的源码判断逻辑--------------- if (ann != null) {     if (requiredConstructor != null) {         // 说明已经存在required=true的构造器,抛异常         throw new BeanCreationException(beanName,                 "Invalid autowire-marked constructor: " + candidate +                 ". Found constructor with 'required' Autowired annotation already: " +                 requiredConstructor);     }     // 判断注解的属性required的值     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);         }         // 把当前构造器存入requiredConstructor         requiredConstructor = candidate;     }     candidates.add(candidate); } 
  • AbstractAutowireCapableBeanFactory的autowireConstructor源码
new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs)
  • ConstructResolver的autowireConstructor方法,流程比较长,总的逻辑是:先选取待使用的构造函数(选取的原则是:构造函数排序,public优先且按参数数量降序,非public按参数数量降序),把构造的实例加入BeanWrapper中,根据实例化策略、构造函数以及构造函数参数实例化Bean(实例化逻辑调用在instantiate方法,源码接着后面。)
BeanWrapperImpl bw = new BeanWrapperImpl(); this.beanFactory.initBeanWrapper(bw);  Constructor<?> constructorToUse = null; ArgumentsHolder argsHolderToUse = null; Object[] argsToUse = null;  // explicitArgs通过getBean方法传入,如果不为空,则直接使用 if (explicitArgs != null) {     argsToUse = explicitArgs; } else {     // 如果在getBean方法没有指定,则尝试从配置文件中解析     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) {         // 解析参数类型,如:给定构造函数是(int, int),通过此方法后("1", "1")会被解析为(1, 1)         argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);     } }  // 没有被缓存 if (constructorToUse == null || argsToUse == null) {     // Spring5更改逻辑顺序,Spring4此段逻辑在[2.]之后     // 1.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) {                 mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;                 mbd.constructorArgumentsResolved = true;                 mbd.resolvedConstructorArguments = EMPTY_ARGS;             }             bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));             return bw;         }     }      // 2. 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();         // 能解析到的构造函数参数个数         minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);     }      /**      * 根据构造函数参数锁定对应的构造函数,根据参数个数匹配,在匹配之前需要完成排序      */     // 构造函数排序,public优先且按参数数量降序,非public按参数数量降序     AutowireUtils.sortConstructors(candidates);     int minTypeDiffWeight = Integer.MAX_VALUE;     Set<Constructor<?>> ambiguousConstructors = null;     Deque<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();         // 配置文件中配置构造函数:1.通过指定参数位置索引创建;2.指定参数名称设定参数值         if (resolvedValues != null) {             try {                 // 从注解中获取参数名称                 String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);                 if (paramNames == null) {                     ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();                     if (pnd != null) {                         paramNames = pnd.getParameterNames(candidate);                     }                 }                 // 根据参数名称和类型创建ArgumentsHolder                 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 ArrayDeque<>(1);                 }                 causes.add(ex);                 continue;             }         } else {             // Explicit arguments given -> arguments length must match exactly.             if (parameterCount != explicitArgs.length) {                 continue;             }             argsHolder = new ArgumentsHolder(explicitArgs);         }          // 探测是否有不确定性的构造函数存在,如:不同构造函数的参数为父子关系         int typeDiffWeight = (mbd.isLenientConstructorResolution() ?                 argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));         // Choose this constructor if it represents the closest match.         // 选择当前最接近的匹配作为构造函数         if (typeDiffWeight < minTypeDiffWeight) {             constructorToUse = candidate;             argsHolderToUse = argsHolder;             argsToUse = argsHolder.arguments;             minTypeDiffWeight = typeDiffWeight;             ambiguousConstructors = null;         } 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);     }      if (explicitArgs == null && argsHolderToUse != null) {         // 把解析的构造函数加入缓存         argsHolderToUse.storeCache(mbd, constructorToUse);     } }  Assert.state(argsToUse != null, "Unresolved constructor arguments"); // 把构造的实例加入BeanWrapper中:根据实例化策略、构造函数以及构造函数参数实例化Bean bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse)); return bw;
  • ConstructResolver的instantiate
try {     InstantiationStrategy strategy = this.beanFactory.getInstantiationStrategy();     if (System.getSecurityManager() != null) {         return AccessController.doPrivileged((PrivilegedAction<Object>) () ->                 strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse),                 this.beanFactory.getAccessControlContext());     }     else {         // 策略默认是SimpleInstantiationStrategy         return strategy.instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse);     } } catch (Throwable ex) {     throw new BeanCreationException(mbd.getResourceDescription(), beanName,             "Bean instantiation via constructor failed", ex); }
  • SimpleInstantiationStrategy的instantiate
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;         });     }     return BeanUtils.instantiateClass(ctor, args); } else {     return instantiateWithMethodInjection(bd, beanName, owner, ctor, args); }
  • BeanUtils#instantiateClass,实例化class的最后一步,先对基本数据类型转换为默认值,最后通过反射实例化
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()); }

Spring源码 - bean创建的生命周期之实例化-createBeanInstance(Spring Framework 5.3.7-SNAPSHO)


本站部分内容转载自网络,版权属于原作者所有,如有异议请联系QQ153890879修改或删除,谢谢!
转载请注明原文链接:Spring源码 – bean创建的生命周期之实例化-createBeanInstance(Spring Framework 5.3.7-SNAPSHO)

你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:

1、点击这里立即申请成为腾讯云VIP客户

2、点击这里立即注册成为天翼云VIP客户

3、点击这里立即申请成为华为云VIP客户

4、点击这里立享阿里云产品终身VIP优惠价

喜欢 (0)
[[email protected]]
分享 (0)