Spring IoC源码:createBean( 上)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: Spring IoC源码:createBean( 上)

文章目录

Spring源码系列:

前言

正文

方法1:createBean

方法2:prepareMethodOverrides

方法3:resolveBeforeInstantiation

方法4:applyBeanPostProcessorsBeforeInstantiation

方法5:doCreateBean

方法6:createBeanInstance

方法7:obtainFromSupplier

方法8: determineConstructorsFromBeanPostProcessors

方法9:autowireConstructor

方法10:resolveConstructorArguments

方法11:createArgumentArray

方法12:instantiateBean

方法13:instantiate

方法14:instantiateClass

总结

Spring源码系列:

Spring IOC源码:简单易懂的Spring IOC 思路介绍

Spring IOC源码:核心流程介绍

Spring IOC源码:ApplicationContext刷新前准备工作

Spring IOC源码:obtainFreshBeanFactory 详解(上)

Spring IOC源码:obtainFreshBeanFactory 详解(中)

Spring IOC源码:obtainFreshBeanFactory 详解(下)

Spring IOC源码:<context:component-scan>源码详解

Spring IOC源码:invokeBeanFactoryPostProcessors 后置处理器详解

Spring IOC源码:registerBeanPostProcessors 详解

Spring IOC源码:实例化前的准备工作

Spring IOC源码:finishBeanFactoryInitialization详解

Spring IoC源码:getBean 详解

Spring IoC源码:createBean( 上)

Spring IoC源码:createBean( 中)

Spring IoC源码:createBean( 下)

Spring IoC源码:finishRefresh 完成刷新详解

前言

前面讲解了getBean方法如何获取创建一个Bean,根据传入的beanName从缓存中进行查找,查询不到则调用createBean方法进行创建,本篇文章深入讲解createBean的创建过程。

正文

回到getSingleton方法中,我们知道参数是ObjectFactory对象,通过调用其getObject方法进行对象的创建过程。

  public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
      //尝试从一级缓存中获取
      Object singletonObject = this.singletonObjects.get(beanName);
      if (singletonObject == null) {
        if (this.singletonsCurrentlyInDestruction) {
          throw new BeanCreationNotAllowedException(beanName,
              "Singleton bean creation not allowed while singletons of this factory are in destruction " +
              "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
        }
        if (logger.isDebugEnabled()) {
          logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
        }
        //添加到singletonsCurrentlyInCreation缓存中
        beforeSingletonCreation(beanName);
        boolean newSingleton = false;
        boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
        if (recordSuppressedExceptions) {
          this.suppressedExceptions = new LinkedHashSet<>();
        }
        try {
          //调用ObjectFactory对象的getObject方法返回实例,getObject方法的实现就是传参时的匿名内部类
          singletonObject = singletonFactory.getObject();
          newSingleton = true;
        }
        catch (IllegalStateException ex) {
          // Has the singleton object implicitly appeared in the meantime ->
          // if yes, proceed with it since the exception indicates that state.
          singletonObject = this.singletonObjects.get(beanName);
          if (singletonObject == null) {
            throw ex;
          }
        }
        catch (BeanCreationException ex) {
          if (recordSuppressedExceptions) {
            for (Exception suppressedException : this.suppressedExceptions) {
              ex.addRelatedCause(suppressedException);
            }
          }
          throw ex;
        }
        finally {
          if (recordSuppressedExceptions) {
            this.suppressedExceptions = null;
          }
          //从singletonsCurrentlyInCreation缓存中移除
          afterSingletonCreation(beanName);
        }
        //添加到一级缓存中,移除二级缓存、三级缓存
        if (newSingleton) {
          addSingleton(beanName, singletonObject);
        }
      }
      return singletonObject;
    }
  }

singletonFactory方法参数值为一个类型为ObjectFactory的匿名内部类,所以调用getObject方法,其实就是调用createBean(beanName, mbd, args),这个方法。

          sharedInstance = getSingleton(beanName, () -> {
            try {
              return createBean(beanName, mbd, args);
            }
            catch (BeansException ex) {
              // Explicitly remove instance from singleton cache: It might have been put there
              // eagerly by the creation process, to allow for circular reference resolution.
              // Also remove any beans that received a temporary reference to the bean.
              destroySingleton(beanName);
              throw ex;
            }
          });

createBean(beanName, mbd, args),见方法1详解

方法1:createBean

  protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
      throws BeanCreationException {
    if (logger.isTraceEnabled()) {
      logger.trace("Creating instance of bean '" + beanName + "'");
    }
    RootBeanDefinition mbdToUse = mbd;
    // Make sure bean class is actually resolved at this point, and
    // clone the bean definition in case of a dynamically resolved Class
    // which cannot be stored in the shared merged bean definition.
    //获取bean对应的class对象,并设置到RootBeanDefinition 定义信息中
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
      mbdToUse = new RootBeanDefinition(mbd);
      mbdToUse.setBeanClass(resolvedClass);
    }
    // Prepare method overrides.
    //解析overrides属性,如xml配置中的lookup-method和replace-method
    try {
      mbdToUse.prepareMethodOverrides();
    }
    catch (BeanDefinitionValidationException ex) {
      throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
          beanName, "Validation of method overrides failed", ex);
    }
    try {
      // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
      //实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例,达到“短路”效果
      //看BeanPostProcessors集合中是否有InstantiationAwareBeanPostProcessor类型的对象,有则尝试进行代理。
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
        return bean;
      }
    }
    catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
          "BeanPostProcessor before instantiation of bean failed", ex);
    }
    try {
    //普通Bean的创建过程
      Object beanInstance = doCreateBean(beanName, mbdToUse, args);
      if (logger.isTraceEnabled()) {
        logger.trace("Finished creating instance of bean '" + beanName + "'");
      }
      return beanInstance;
    }
    catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
      // A previously detected exception with proper bean creation context already,
      // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
      throw ex;
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
    }
  }

mbdToUse.prepareMethodOverrides(),见方法2详解

resolveBeforeInstantiation(beanName, mbdToUse),见方法3详解

doCreateBean(beanName, mbdToUse, args),见方法5详解

方法2:prepareMethodOverrides

  public void prepareMethodOverrides() throws BeanDefinitionValidationException {
    // Check that lookup methods exist and determine their overloaded status.
    //判断当前Bean定义信息中是否有methodOverrides标识
    if (hasMethodOverrides()) {
      //遍历校验当前bean中是否存在该方法
      getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
    }
  }
  /**
   * Validate and prepare the given method override.
   * Checks for existence of a method with the specified name,
   * marking it as not overloaded if none found.
   * @param mo the MethodOverride object to validate
   * @throws BeanDefinitionValidationException in case of validation failure
   */
  protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
    //查询校验是否存在override属性值对应的方法
    int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
    if (count == 0) {
      throw new BeanDefinitionValidationException(
          "Invalid method override: no method with name '" + mo.getMethodName() +
          "' on class [" + getBeanClassName() + "]");
    }
    else if (count == 1) {
      // Mark override as not overloaded, to avoid the overhead of arg type checking.
      mo.setOverloaded(false);
    }
  }

当前bean定义信息中如果有overrides属性,则校验所配置的方法名称在该bean中是否存在。

方法3:resolveBeforeInstantiation

  protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    //默认该属性为false
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
      // Make sure bean class is actually resolved at this point.
      //不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor
      if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        //获取beanName对应的class对象
        Class<?> targetType = determineTargetType(beanName, mbd);
        if (targetType != null) {
          //执行InstantiationAwareBeanPostProcessor类型的postProcessBeforeInstantiation方法,并返回实例
          bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
          if (bean != null) {
            //执行所有BeanPostProcessor后置处理器的postProcessAfterInitialization
            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
          }
        }
      }
      mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
  }

isSynthetic一般用来跳过beanPostProcessor执行。

applyBeanPostProcessorsBeforeInstantiation(targetType, beanName),见方法4详解

方法4:applyBeanPostProcessorsBeforeInstantiation

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    //遍历执行InstantiationAwareBeanPostProcessor类型对象的postProcessBeforeInstantiation方法
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
        Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
        if (result != null) {
          return result;
        }
      }
    }
    return null;
  }

这个有点类似拦截器,通过自定义一个InstantiationAwareBeanPostProcessor类型的后置处理器,并bean进行处理,返回最终的实例对象

方法5:doCreateBean

  protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
      throws BeanCreationException {
    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    //如果是单例并且是FactoryBean则尝试移除
      instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
      //创建Bean实例,通过策略进行创建,如果选择有参构造或无参构造
      instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    //获取当前实例对象
    final Object bean = instanceWrapper.getWrappedInstance();
    //当前实例的Calss对象
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
      //设置当前bean定义信息的目标类型
      mbd.resolvedTargetType = beanType;
    }
    // Allow post-processors to modify the merged bean definition.
    synchronized (mbd.postProcessingLock) {
      if (!mbd.postProcessed) {
        try {
          //执行MergedBeanDefinitionPostProcessor类型后置处理器的postProcessMergedBeanDefinition方法,
          //如@Autowire注解,就是通过该后置处理器进行解析
          applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
        }
        catch (Throwable ex) {
          throw new BeanCreationException(mbd.getResourceDescription(), beanName,
              "Post-processing of merged bean definition failed", ex);
        }
        mbd.postProcessed = true;
      }
    }
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    //如果是单例,允许循环依赖,并且beanName正在创建中
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
        isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
      if (logger.isTraceEnabled()) {
        logger.trace("Eagerly caching bean '" + beanName +
            "' to allow for resolving potential circular references");
      }
      //包装成FactoryObject对象,并添加到三级缓存中
      addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
      //初始化过程,进行属性注入。该过程递归创建其依赖的属性。如果A中有B,B中有C,则创建B跟C。
      populateBean(beanName, mbd, instanceWrapper);
      //该过程执行后置处理器的before方法,bean的init方法,后置处理器的after方法,可能会生成新的bean对象
      exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
      if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
        throw (BeanCreationException) ex;
      }
      else {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
      }
    }
    if (earlySingletonExposure) {
      //从缓存中获取,因为上面我们将其添加到三级缓存中,从三级缓存中获取会调用FactoryObject对象的getObject方法,可能会触发AOP代理。返回代理对象
      Object earlySingletonReference = getSingleton(beanName, false);
      if (earlySingletonReference != null) {
        //如果bean对象还是原来的,则将三级缓存中获取的对象赋值过去
        if (exposedObject == bean) {
          exposedObject = earlySingletonReference;
        }
        //如果exposedObject在initializeBean方法中被增强 && 不允许在循环引用的情况下使用注入原始bean实例
        else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
          //  获取依赖当前beanName的所有bean名称
          String[] dependentBeans = getDependentBeans(beanName);
          Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
          //尝试移除这些bean的实例,因为这些bean依赖的bean已经被增强了,他们依赖的bean相当于脏数据
          for (String dependentBean : dependentBeans) {
            if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
              actualDependentBeans.add(dependentBean);
            }
          }
          if (!actualDependentBeans.isEmpty()) {
            throw new BeanCurrentlyInCreationException(beanName,
                "Bean with name '" + beanName + "' has been injected into other beans [" +
                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                "] in its raw version as part of a circular reference, but has eventually been " +
                "wrapped. This means that said other beans do not use the final version of the " +
                "bean. This is often the result of over-eager type matching - consider using " +
                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
          }
        }
      }
    }
    // Register bean as disposable.
    try {
      //注册用于销毁的bean,执行销毁操作的有三种:自定义destroy方法、DisposableBean接口、DestructionAwareBeanPostProcessor
      registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    return exposedObject;
  }

createBeanInstance(beanName, mbd, args),见方法6详解

方法6:createBeanInstance

  protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    //解析class信息
    Class<?> beanClass = resolveBeanClass(mbd, beanName);
    //判断 beanClass不为空 && beanClass不是public修饰 && 该bean不允许访问非公共构造函数和方法,则抛异常
    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
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
      return obtainFromSupplier(instanceSupplier, beanName);
    }
    //使用工厂方法实例化bean对象
    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?
    //调用SmartInstantiationAwareBeanPostProcessor类型的determineCandidateConstructors方法,返回构造函数
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    //解析的构造器不为空 || 注入类型为构造函数自动注入 || bean定义中有构造器参数 || 传入参数不为空
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
      return autowireConstructor(beanName, mbd, ctors, args);
    }
    // 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);
  }

obtainFromSupplier(instanceSupplier, beanName),见方法7详解


determineConstructorsFromBeanPostProcessors(beanClass, beanName),见方法8详解


autowireConstructor(beanName, mbd, null, null);,见方法9详解


instantiateBean(beanName, mbd),见方法12详解

方法7:obtainFromSupplier

  protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
    Object instance;
    //获取当前正在创建的BeanName
    String outerBean = this.currentlyCreatedBean.get();
    //设置当前beanName到当前线程中
    this.currentlyCreatedBean.set(beanName);
    try {
      //调用Supplier的get自定义方法,创建实例对象
      instance = instanceSupplier.get();
    }
    finally {
      if (outerBean != null) {
        this.currentlyCreatedBean.set(outerBean);
      }
      else {
        this.currentlyCreatedBean.remove();
      }
    }
    if (instance == null) {
      instance = new NullBean();
    }
    //封装成BeanWrapper 包装类
    BeanWrapper bw = new BeanWrapperImpl(instance);
    initBeanWrapper(bw);
    return bw;
  }

方法8: determineConstructorsFromBeanPostProcessors

  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;
          //调用determineCandidateConstructors方法,按照策略查询构造函数
          //如果bean的构造函数带有@Autowire注解或有且仅有一个有参构造函数则会被解析到
          Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
          if (ctors != null) {
            return ctors;
          }
        }
      }
    }
    return null;
  }

加果有多个@Autowired,required为true,不管有没有默认构造方法,会报异常

如果只有一个@Autowired,required,为false,但有默认构造方,会报警告

其他情况都可以,但是以有@Autowired的构造方法优先,然后才是默认构造方法

方法9:autowireConstructor

  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) {
    BeanWrapperImpl bw = new BeanWrapperImpl();
    //初始化设置
    this.beanFactory.initBeanWrapper(bw);
    //最终使用的构造器
    Constructor<?> constructorToUse = null;
    //最终用于实例化的参数Holder
    ArgumentsHolder argsHolderToUse = null;
    //最终使用的参数值
    Object[] argsToUse = null;
    //如果有带参数,则进行赋值给argsToUse 
    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) {
        argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true);
      }
    }
    if (constructorToUse == null || argsToUse == null) {
      // Take specified constructors, if any.
      //将传递进来的构造器赋值给最终使用的构造器
      Constructor<?>[] candidates = chosenCtors;
      if (candidates == null) {
        //获取当前bean的class对象
        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()) {
        //获取构造函数,判断参数值是否为0
        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.
      //判断是否有传递进来的构造函数,如果@Autowire修饰的构造函数,则会有值
      boolean autowiring = (chosenCtors != null ||
          mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
      ConstructorArgumentValues resolvedValues = null;
      //最少参数个数
      int minNrOfArgs;
      //如果有传递进来的参数,则取传递的个数
      if (explicitArgs != null) {
        minNrOfArgs = explicitArgs.length;
      }
      else {
        //获得mbd的构造函数的参数值(indexedArgumentValues:带index的参数值;genericArgumentValues:通用的参数值)
        ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
        resolvedValues = new ConstructorArgumentValues();
        //将参数值分类封装成ConstructorArgumentValues,并返回参数个数
        minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
      }
      //对构造函数进行排序,先按方法修饰符排序:public排非public前面,再按构造函数参数个数排序:参数多的排前面
      AutowireUtils.sortConstructors(candidates);
      //比较差异值,用于构造器选择
      int minTypeDiffWeight = Integer.MAX_VALUE;
      Set<Constructor<?>> ambiguousConstructors = null;
      LinkedList<UnsatisfiedDependencyException> causes = null;
      //遍历构造器
      for (Constructor<?> candidate : candidates) {
        //获取构造器参数类型
        Class<?>[] paramTypes = candidate.getParameterTypes();
        //如果已经确定好了构造器了,这里就跳过了,因为遍历的构造函数已经排过序,后面不会有更合适的候选者了
        if (constructorToUse != null && argsToUse != null && argsToUse.length > paramTypes.length) {
          // Already found greedy constructor that can be satisfied ->
          // do not look any further, there are only less greedy constructors left.
          break;
        }
        //如果参数个数小于最小参数个数,则不符合条件,跳过
        if (paramTypes.length < minNrOfArgs) {
          continue;
        }
        ArgumentsHolder argsHolder;
        if (resolvedValues != null) {
          try {
          // 解析使用ConstructorProperties注解的构造函数参数
            String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, paramTypes.length);
            if (paramNames == null) {
              //获取参数名称查找解析器
              ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
              if (pnd != null) {
                //解析出构造器的参数名称
                paramNames = pnd.getParameterNames(candidate);
              }
            }
            //通过参数类型和参数名解析构造函数或工厂方法所需的参数(如果参数是其他bean,则会解析依赖的bean)
            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.
          //如果当前遍历的构造函数参数个数与explicitArgs长度不相同,则跳过该构造函数
          if (paramTypes.length != explicitArgs.length) {
            continue;
          }
          //使用传递进来的值构建ArgumentsHolder
          argsHolder = new ArgumentsHolder(explicitArgs);
        }
        //根据mbd的解析构造函数模式(true: 宽松模式(默认),false:严格模式),
          // 将argsHolder的参数和paramTypes进行比较,计算paramTypes的类型差异权重值
        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) {
        //添加到ambiguousConstructors中
          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");
    //实例化
    bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
    return bw;
  }

首先会判断构造函数是否只有一个,并且是无参、没有参数值,则使用无参构造器创建实例。否则获取构造函数,按权限public排在非public前面,参数多的排在参数少的前面进行排序。解析看当前需要注入的参数有多少个,根据构造器参数不小于实际需要注入的参数个数进行过滤,根据不同的模式选择策略比较参数的权重,计算权重值越小,则构造器越符合要求,最后使用最终确定构造器进行创建。


这里方法比较巧妙的设计,第一次执行该方法选择构造器流程后,会将构造器、ArgumentsHolder等存储起来,如果是原型模式(多例),则每次获取对象都会获取,这样的好处是避免耗费系统性能,因为对于实例化过程而已,最终都是使用同个构造器。


resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues),见方法10详解

createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1),见方法12详解


根据例子进行DEBUG,比较好理解:

public class Address {
  String province;
  String city;
  public String getProvince() {
    return province;
  }
  public void setProvince(String province) {
    this.province = province;
  }
  public String getCity() {
    return city;
  }
  public void setCity(String city) {
    this.city = city;
  }
}
public class Teacher implements Person {
  private String name;
  private String age;
  private Address address;
  public Teacher(String name, String age, Address address, List<String> list) {
    this.name = name;
    this.age = age;
    this.address = address;
  }
  public Teacher(String name, String age, Address address) {
    this.name = name;
    this.age = age;
    this.address = address;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getAge() {
    return age;
  }
  public void setAge(String age) {
    this.age = age;
  }
  public Address getAddress() {
    return address;
  }
  public void setAddress(Address address) {
    this.address = address;
  }
  @Override
  public void work() {
    System.out.printf("我是:"+name+",今年:"+age+":工作中");
  }
  @Override
  public void sleep() {
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
  <bean id="address"  class="service.Address"></bean>
  <bean  id="teacher" name="teacher" class="service.impl.Teacher">
    <constructor-arg index="0" value="zhangsan"></constructor-arg>
    <constructor-arg  name="age" value="13"></constructor-arg>
    <constructor-arg index="2" ref="address"></constructor-arg>
    <constructor-arg index="3" >
      <list>
        <value>zhudachang1</value>
        <value>zhudachang2</value>
        <value>zhudachang3</value>
      </list>
    </constructor-arg>
  </bean>
</beans>

编写入口:

  public static void main(String[] args) {
    ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("application-context.xml");
    Teacher teacher = (Teacher) applicationContext.getBean("teacher");
  }

方法10:resolveConstructorArguments

private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
      ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
    TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
    TypeConverter converter = (customConverter != null ? customConverter : bw);
    BeanDefinitionValueResolver valueResolver =
        new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
    //设置xml配置的构造函数参数个数
    int minNrOfArgs = cargs.getArgumentCount();
    //遍历
    for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
      //获取xml配置的构造函数注入index的值
      int index = entry.getKey();
      if (index < 0) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Invalid constructor argument index: " + index);
      }
      //判断配置的下标值是否大于配置参数的个数
      if (index > minNrOfArgs) {
        minNrOfArgs = index + 1;
      }
      //获取需要注入的值
      ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
      //判断是否解析过了,如果解析过则将下标跟注入值添加到resolvedValues中,
      if (valueHolder.isConverted()) {
        resolvedValues.addIndexedArgumentValue(index, valueHolder);
      }
      else {
        //将值进行转换封装创建,如 为BeanDefinition,进行实例化创建
        Object resolvedValue =
            valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
        //将生成的对象进行封装
        ConstructorArgumentValues.ValueHolder resolvedValueHolder =
            new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
        //设置原始值
        resolvedValueHolder.setSource(valueHolder);
        //添加到ConstructorArgumentValues的indexedArgumentValues集合中
        resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
      }
    }
    //遍历其他类型注入方式
    for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
      //判断是否完成转换
      if (valueHolder.isConverted()) {
        resolvedValues.addGenericArgumentValue(valueHolder);
      }
      else {
        //获取创建后的实例值
        Object resolvedValue =
            valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
        //封装成ValueHolder 对象
        ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(
            resolvedValue, valueHolder.getType(), valueHolder.getName());
        //设置初始对象值
        resolvedValueHolder.setSource(valueHolder);
        //添加到ConstructorArgumentValues的genericArgumentValues集合中
        resolvedValues.addGenericArgumentValue(resolvedValueHolder);
      }
    }
    return minNrOfArgs;
  }

方法11: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来存放匹配到的参数
    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对象,如String
      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 
        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!
        //添加到ValueHolder集合中
        usedValueHolders.add(valueHolder);
        //获取原始值
        Object originalValue = valueHolder.getValue();
        Object convertedValue;
        if (valueHolder.isConverted()) {
          //如果转换过,则直接进行赋值
          convertedValue = valueHolder.getConvertedValue();
          //添加到预选参数中
          args.preparedArguments[paramIndex] = convertedValue;
        }
        else {
          //将构造函数跟下标封装成MethodParameter 
          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;
            //添加sourceValue作为预备参数
            args.preparedArguments[paramIndex] = sourceValue;
          }
        }
        //将convertedValue作为args在paramIndex位置的参数
        args.arguments[paramIndex] = convertedValue;
        //将originalValue作为args在paramIndex位置的原始参数
        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.
        //如果不是@Autowire注解的构造函数,则抛异常
        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 {
          //如果是自动装配,则调用用于解析自动装配参数的方法,返回的结果为依赖的bean实例对象
             // 例如:@Autowire修饰构造函数,自动注入构造函数中的参数bean就是在这边处理
          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);
        }
      }
    }
    //依赖了其他的bean,则注册依赖关系
    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;
  }

方法12:instantiateBean

  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 {
        //获取策略进行实例化
        beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
      }
      //封装成BeanWrapper 对象
      BeanWrapper bw = new BeanWrapperImpl(beanInstance);
      //初始化设置BeanWrapper属性值
      initBeanWrapper(bw);
      return bw;
    }
    catch (Throwable ex) {
      throw new BeanCreationException(
          mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
  }

getInstantiationStrategy().instantiate(mbd, beanName, parent),见方法13详解

方法13:instantiate

@Override
  public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // Don't override the class with CGLIB if no overrides.
    if (!bd.hasMethodOverrides()) {
      Constructor<?> constructorToUse;
      synchronized (bd.constructorArgumentLock) {
        //获取构造函数
        constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
        if (constructorToUse == null) {
          //获取class对象
          final Class<?> clazz = bd.getBeanClass();
          if (clazz.isInterface()) {
            throw new BeanInstantiationException(clazz, "Specified class is an interface");
          }
          try {
            if (System.getSecurityManager() != null) {
              constructorToUse = AccessController.doPrivileged(
                  (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
            }
            else {
            //获取无参构造器
              constructorToUse = clazz.getDeclaredConstructor();
            }
            //设置无参构造器,下次实例化时可直接获取使用
            bd.resolvedConstructorOrFactoryMethod = constructorToUse;
          }
          catch (Throwable ex) {
            throw new BeanInstantiationException(clazz, "No default constructor found", ex);
          }
        }
      }
      //实例化
      return BeanUtils.instantiateClass(constructorToUse);
    }
    else {
      // Must generate CGLIB subclass.
      //使用cglib方式进行实例化
      return instantiateWithMethodInjection(bd, beanName, owner);
    }
  }

BeanUtils.instantiateClass(constructorToUse),见方法14详解

方法14:instantiateClass

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
    Assert.notNull(ctor, "Constructor must not be null");
    try {
      //如果构造函数非Public,则设置Accessible权限
      ReflectionUtils.makeAccessible(ctor);
      //判断是否使用kotlin语言,如果是则使用kotlin语言进行实例化
      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];
            //判断类型是否是基本数据类型,并尝试从默认类型中获取值
            //void、Integer、Double、Short、Long、Character、Byte、Boolean、Float
            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());
    }
  }

限于篇幅,下篇文章继续讲解实例化之后的流程。

总结

1、在实例构造函数实例化创建前,会调用InstantiationAwareBeanPostProcessor类型的postProcessBeforeInstantiation方法,并返回实例,如果实例不为空,则不会走后面的doCreateBean流程。


2、进入创建Bean环节,判断是否使用工厂方法或Supplier方式进行实例化,并返回实例。不满足上述两种创建过程,则会从bean的定义信息中查询是否有确定的构造器、注入参数等,有则直接使用确定的构造器及参数进行实例化。


3、通过后置器处理器SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法进行处理并返回符合条件的构造函数,如果bean的构造函数带有@Autowire注解或有且仅有一个带参的构造函数则返回。


4、使用autowireConstructor自动构造函数的方式进行创建时,如果没有传递构造函数数组,则会获取所有的构造函数数组,并对数据进行排序,过滤掉构造函数参数个数小于需要注入的参数个数。对注入参数进行转换,实例化创建等。如果没有传递参数、并且构造函数使用了@Autowire注解,则会尝试查询创建工厂中所匹配的对象。


5、使用无参构造函数进行实例化





目录
相关文章
|
14天前
|
XML Java 测试技术
spring复习01,IOC的思想和第一个spring程序helloWorld
Spring框架中IOC(控制反转)的思想和实现,通过一个简单的例子展示了如何通过IOC容器管理对象依赖,从而提高代码的灵活性和可维护性。
spring复习01,IOC的思想和第一个spring程序helloWorld
|
5天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
37 9
|
2天前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
4 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
11天前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
23 4
|
14天前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
2月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
3月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。
|
3月前
|
Java 应用服务中间件 开发者
Java面试题:解释Spring Boot的优势及其自动配置原理
Java面试题:解释Spring Boot的优势及其自动配置原理
102 0
|
2天前
|
数据采集 监控 Java
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
本文是关于SpringBoot日志的详细教程,涵盖日志的定义、用途、SLF4J框架的使用、日志级别、持久化、文件分割及格式配置等内容。
9 0
SpringBoot日志全方位超详细手把手教程,零基础可学习 日志如何配置及SLF4J的使用......
|
6天前
|
缓存 NoSQL Java
Springboot自定义注解+aop实现redis自动清除缓存功能
通过上述步骤,我们不仅实现了一个高度灵活的缓存管理机制,还保证了代码的整洁与可维护性。自定义注解与AOP的结合,让缓存清除逻辑与业务逻辑分离,便于未来的扩展和修改。这种设计模式非常适合需要频繁更新缓存的应用场景,大大提高了开发效率和系统的响应速度。
24 2