聊聊 @Configuration 注解

Vue3 - Element Plus上传组件el-upload上传多个文件时,让on-change监听事件仅执行一次并获取最终文件列表方法(开启多选文件并手动上传,拿到文件列表统一循环调用接口上传) vue3,elementplus,Upload上传,el-upload,文件上传组件,上传组件on-change里执行多次,取消自动上传后change重复执行问题,upload上传多个文件后导致on-change执行多次拿不到最终文件列表,Element-plus的upload组件on-change不断执行怎么办,上传多个文件多次执行调用,上传多个文件时如何只执行一次on-change方法拿到最终的文件列表,vue3elementplus上传组件开启多个上传后导致change方法执行好几次,仅调用一 阅读详情

分享一个小的知识点,在一个类上添加 @Configuration 注解,这个类就是配置类。

提出有三个问题:

  • 如果我们没有添加这个注解程序还能不能运行?

  • 如果能是为什么?不能又是为什么?

  • 如果能,加不加 @Configuration 注解有什么区别?

我们先创建一个简单的程序。

配置类:

@Configuration
@ComponentScan("com.future")
public class ConfigClass {

}

dao层用来输出:

@Repository
public class IndexDao {

    public void query() {
        System.out.println("query");
    }
}

测试类:

public class Test {

    public static void main(String[] args) {
        // 调用 AnnotationConfigApplicationContext 类的无参构造方法,初始化两个对象
        // 一个是 AnnotatedBeanDefinitionReader()
        // 另一个是 ClassPathBeanDefinitionScanner()
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();

        // Register one or more component classes to be processed.
        context.register(ApplicationConfig.class);

        // 初始化 Spring 环境
        context.refresh();

        IndexDao indexDao = context.getBean(IndexDao.class);
        indexDao.query();
    }
}

检查一个类是否含有 @Configuration 注解,我们需要进入 refresh() 方法。

@Override
public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        ......

        try {
            // Allows post-processing of the bean factory in context subclasses.
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            registerBeanPostProcessors(beanFactory);

            ......
  }
  catch (BeansException ex) {
    ......
  }
  finally {
    ......
  }
}

找到 invokeBeanFactoryPostProcessors() 方法,意思是说在上下文中调用注册为 bean 的工厂处理器。

进入这个方法。


/**
 * Instantiate and invoke all registered BeanFactoryPostProcessor beans,
 * respecting explicit order if given.
 * <p>Must be called before singleton instantiation.
 */
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

    // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
    // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
    if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
        beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
        beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    }
}

这个方法注释为:实例化和调用所有注册的 BeanFactoryPostProcessor bean。

该方法调用了 invokeBeanFactoryPostProcessors() 方法,进入这个方法。

在 invokeBeanFactoryPostProcessors() 方法中,会调用另外的方法 invokeBeanDefinitionRegistryPostProcessors()。

进入 invokeBeanDefinitionRegistryPostProcessors() 方法。

// 找到这行代码。
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);

参数:currentRegistryProcessors,是一个 List 集合,里边存放的是 Spring 内部自己实现的 eanDefinitionRegistryPostProcessor 接口的对象。

进入 invokeBeanDefinitionRegistryPostProcessors() 方法,

/**
 * Invoke the given BeanDefinitionRegistryPostProcessor beans.
 */
private static void invokeBeanDefinitionRegistryPostProcessors(
        Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

注释是说:调用给定的 BeanDefinitionRegistryPostProcessor 的 bean。

里边只有一个方法,进入 postProcessBeanDefinitionRegistry() 方法。该方法为接口方法,调用了 ConfigurationClassPostProcessor 实现类的的方法。

/**
 * Derive further bean definitions from the configuration classes in the registry.
 */
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    if (this.factoriesPostProcessed.contains(registryId)) {
        throw new IllegalStateException(
                "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    this.registriesPostProcessed.add(registryId);

    processConfigBeanDefinitions(registry);
}

注释大概意思是从注册表中的配置类派生更多的bean定义。

进入 processConfigBeanDefinitions() 这个方法。

/**
 * Build and validate a configuration model based on the registry of
 * {@link Configuration} classes.
 */

意思为:建立和验证一个配置模型给予注册表的 Configuration 类。

找到源码中如下的部分。

for (String beanName : candidateNames) {
    BeanDefinition beanDef = registry.getBeanDefinition(beanName);
    if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
            ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
        if (logger.isDebugEnabled()) {
            logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
        }
    }
    else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
        configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
    }
}

这个循环就是我们要找的,首先通过 beanName,获得 BeanDefinition 对象,判断对象是否为 Full 或者 Lite,如果都不是那么说明配置类还没有被处理过,需要进入 else-if 进行处理。

在 if 判断中调用了 checkConfigurationClassCandidate() 方法,进入该方法。

找到如下代码片段。

if (isFullConfigurationCandidate(metadata)) {
    beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (isLiteConfigurationCandidate(metadata)) {
    beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
    return false;
}

判断当前这个 bd 中是否存在 @Configuration 这个注解,如果存在,则Spring 认为它是一个全注解的类,也就是 if 判断中,将 CONFIGURATION_CLASS_ATTRIBUTE 属性设置为 full,那么进入 if 判断,如果没有加,则 Spring认为它是一个部分注解类,将 CONFIGURATION_CLASS_ATTRIBUTE 属性设置为 lite,进入 else-if 判断。

public static boolean isFullConfigurationCandidate(AnnotationMetadata metadata) {
   return metadata.isAnnotated(Configuration.class.getName());
}

判断这个类是否有 @Configuration 注解,有的话返回 true,否则返回 false。

public static boolean isLiteConfigurationCandidate(AnnotationMetadata metadata) {
    // Do not consider an interface or an annotation...
    if (metadata.isInterface()) {
        return false;
    }

    // Any of the typical annotations found?
    for (String indicator : candidateIndicators) {
        if (metadata.isAnnotated(indicator)) {
            return true;
        }
    }

    // Finally, let's look for @Bean methods...
    try {
        return metadata.hasAnnotatedMethods(Bean.class.getName());
    }
    catch (Throwable ex) {
        if (logger.isDebugEnabled()) {
            logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
        }
        return false;
    }
}

在循环当中,注释说找到任何一个典型的注解,有哪些注解,我们看 candidateIndicators 这个对象,查看这个对象它是一个 Set 集合,这个集合会在初始化过程中添加四个对象的 name。

private static final Set<String> candidateIndicators = new HashSet<>(8);

static {
    candidateIndicators.add(Component.class.getName());
    candidateIndicators.add(ComponentScan.class.getName());
    candidateIndicators.add(Import.class.getName());
    candidateIndicators.add(ImportResource.class.getName());
}

结合 for 循环来看,只要配置类中含有这四个注解 (@Component、@ComponentScan、@Import、@ImportResource),就会返回 true。

返回到如下代码。

if (isFullConfigurationCandidate(metadata)) {
    beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
else if (isLiteConfigurationCandidate(metadata)) {
    beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
}
else {
    return false;
}

所以可以看到,只要是 @Configuration、@Component、@ComponentScan、@Import、@ImportResource,这五个注解,都会在后边返回 true。

所以只要配置类中使用这五个注解中的一个都会在 processConfigBeanDefinitions() 方法返回 true,并将这个类放到 BeanDefinitionHolder 类型的 List 集合中。

else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
    configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}

现在知道,为什么没有 @Configuration 注解,程序也可以运行。

现在说第二个问题,加与不加有什么区别?

在 test 类当中添加一行代码,可以得到 applicationConfig 的类型。

ApplicationConfig applicationConfig = context.getBean(ApplicationConfig.class);

加 @Configuration 注解

不加 @Configuration 注解

体现着源码中:

首先进入 refresh() 方法,在该方法中找到 invokeBeanFactoryPostProcessors() 方法,并进入,在该方法中找到 invokeBeanFactoryPostProcessors() 方法,并进入。

找到如下代码:

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);

这两个方法唯一不同的是参数。

List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

区别就是存放的对象不同,BeanFactoryPostProcessor 是父类,而 BeanDefinitionRegistryPostProcessor 即是父类,也是子类。

从前面的代码中就可以看出来。

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
   if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
      BeanDefinitionRegistryPostProcessor registryProcessor =
            (BeanDefinitionRegistryPostProcessor) postProcessor;
      registryProcessor.postProcessBeanDefinitionRegistry(registry);
      registryProcessors.add(registryProcessor);
   }
   else {
      regularPostProcessors.add(postProcessor);
   }
}

如果 postProcessor 是 BeanDefinitionRefistryPostProcessor 的子类,那么就把这个类放到 registryProcessor 中,否则放到 regularPostProcessors 中。

进入 invokeBeanFactoryPostProcessors() 方法。

/**
 * Invoke the given BeanFactoryPostProcessor beans.
 */
private static void invokeBeanFactoryPostProcessors(
      Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

   for (BeanFactoryPostProcessor postProcessor : postProcessors) {
      postProcessor.postProcessBeanFactory(beanFactory);
   }
}

再进入 postProcessBeanFactory() 方法,这是接口方法,要进入 ConfigurationClassPostProcessor 类的 postProcessBeanFactory() 方法。

/**
 * Prepare the Configuration classes for servicing bean requests at runtime
 * by replacing them with CGLIB-enhanced subclasses.
 */
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   int factoryId = System.identityHashCode(beanFactory);
   if (this.factoriesPostProcessed.contains(factoryId)) {
      throw new IllegalStateException(
            "postProcessBeanFactory already called on this post-processor against " + beanFactory);
   }
   this.factoriesPostProcessed.add(factoryId);
   if (!this.registriesPostProcessed.contains(factoryId)) {
      // BeanDefinitionRegistryPostProcessor hook apparently not supported...
      // Simply call processConfigurationClasses lazily at this point then.
      processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
   }

   enhanceConfigurationClasses(beanFactory);
   beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

enhanceConfigurationClasses() 这个方法就是我们要找的,它的作用是给配置类 ( @Configuration ) 产生 CGLIB 代理。

进入 enhanceConfigurationClasses() 方法,找到如下的代码。

Map<String, AbstractBeanDefinition> configBeanDefs = new LinkedHashMap<>();
for (String beanName : beanFactory.getBeanDefinitionNames()) {
   BeanDefinition beanDef = beanFactory.getBeanDefinition(beanName);
   if (ConfigurationClassUtils.isFullConfigurationClass(beanDef)) {
      if (!(beanDef instanceof AbstractBeanDefinition)) {
         throw new BeanDefinitionStoreException("Cannot enhance @Configuration bean definition '" +
               beanName + "' since it is not stored in an AbstractBeanDefinition subclass");
      }
      else if (logger.isInfoEnabled() && beanFactory.containsSingleton(beanName)) {
         logger.info("Cannot enhance @Configuration bean definition '" + beanName +
               "' since its singleton instance has been created too early. The typical cause " +
               "is a non-static @Bean method with a BeanDefinitionRegistryPostProcessor " +
               "return type: Consider declaring such methods as 'static'.");
      }
      configBeanDefs.put(beanName, (AbstractBeanDefinition) beanDef);
   }
}
if (configBeanDefs.isEmpty()) {
   // nothing to enhance -> return immediately
   return;
}

for 循环中有 if 判断,判断是否是一个全注解的类,也就是拥有 full 属性值,如果是全注解的类,那么会将这个类添加到一个 Map 中,否则 Map 为空,直接返回。

这里就可以进行我们 Test 测试,在这里打上断点,查看有或者没有 @Configuration 注解,是否会进入或者不进入第二个 if 判断。

当有 @Configuration 注解,它会跳过 if 判断。

当没有 @Configuration 注解,它会进入 if 判断,直接返回。

当跳过 if 判断后,就会执行 CGLIB 代理。

我们可以看到两个注释,第一个注释,如果 @Configuration 注解的类被代理,那么它总是代理这个目标类。

也就是说如果加了 @Configuration 注解,那么我们得到的就是一个被 CGLIB 代理的代理类。

第二个注释,设置一个增强的子类,对于用户指定的bean类。

我们指定的类是含有 @Configuration 注解的类,所以这里的 configClass 就是我们的 ConfigClass 类。


ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
for (Map.Entry<String, AbstractBeanDefinition> entry : configBeanDefs.entrySet()) {
    AbstractBeanDefinition beanDef = entry.getValue();
    // If a @Configuration class gets proxied, always proxy the target class
    beanDef.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
    try {
        // Set enhanced subclass of the user-specified bean class
        Class<?> configClass = beanDef.resolveBeanClass(this.beanClassLoader);
        if (configClass != null) {
            Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);
            if (configClass != enhancedClass) {
                if (logger.isTraceEnabled()) {
                    logger.trace(String.format("Replacing bean definition '%s' existing class '%s' with " +
                            "enhanced class '%s'", entry.getKey(), configClass.getName(), enhancedClass.getName()));
                }
                beanDef.setBeanClass(enhancedClass);
            }
        }
    }
    catch (Throwable ex) {
        throw new IllegalStateException("Cannot load configuration class: " + beanDef.getBeanClassName(), ex);
    }
}

我们进入 enhance() 这个方法。

Class<?> enhancedClass = enhancer.enhance(configClass, this.beanClassLoader);

先看到一个 if,是说如果这个类已经被增强了,那么直接返回这个增强的类。

如果没有被代理,就先调用 newEnhancer() 方法创建一个增强器 Enhancer。

再看 createClass() 方法,使用这个增强器,生成代理类的 class 对象。

createClass() 方法上的注释也说了,使用增强器生成一个超类的子类,确保回调注册了新的子类。

/**
 * Loads the specified class and generates a CGLIB subclass of it equipped with
 * container-aware callbacks capable of respecting scoping and other bean semantics.
 * @return the enhanced subclass
 */
public Class<?> enhance(Class<?> configClass, @Nullable ClassLoader classLoader) {
  if (EnhancedConfiguration.class.isAssignableFrom(configClass)) {
    if (logger.isDebugEnabled()) {
      logger.debug(String.format("Ignoring request to enhance %s as it has " +
          "already been enhanced. This usually indicates that more than one " +
          "ConfigurationClassPostProcessor has been registered (e.g. via " +
          "<context:annotation-config>). This is harmless, but you may " +
          "want check your configuration and remove one CCPP if possible",
          configClass.getName()));
    }
    return configClass;
  }
  Class<?> enhancedClass = createClass(newEnhancer(configClass, classLoader));
  if (logger.isTraceEnabled()) {
    logger.trace(String.format("Successfully enhanced %s; enhanced class name is: %s",
        configClass.getName(), enhancedClass.getName()));
  }
  return enhancedClass;
}

到此我们就解决了刚开始说的三个问题。

有兴趣的同学可以关注我的个人公众号,期待我们共同进步!!!

手把手教你学simulink(26.8)--控制算法场景示例:基于强化学习的无人机姿态稳定控制系统 首先,我们需要定义无人机的姿态稳定控制环境。环境包括无人机的状态(姿态角、角速度等)和动作(电机转速)。我们还需要定义奖励函数,用于评估控制器的表现。matlab深色版本% 定义环境% 定义状态空间% 12个状态变量% 定义动作空间% 电机转速范围奖励函数用于评估控制器的表现。我们可以根据无人机的姿态误差、角速度误差以及控制输入的变化率来设计奖励函数。具体来说,当无人机的姿态接近设定值时,给予正奖励;当姿态误差较大或控制输入变化剧烈时,给予负奖励。matlab深色版本。 阅读详情

相关推荐

避坑指南:PyTorch ConvLSTM参数配置的那些坑(hidden_dim/kernel_size/num_layers详解)

本文深度解析PyTorch ConvLSTM中hidden_dim、kernel_size和num_layers三大核心参数的配置技巧,提供实战指南和性能优化建议。通过实验数据揭示参数组合的内在规律,帮助开发者避免常见配置陷阱,提升时空序列建模效果。特别针对视频预测、气象预报等应用场景,给出黄金参数组合方案和调试技巧。

vv45678的博客 700

@Configuration注解的作用

1.@Configuration使用   官方文档描述:   用@Configuration注释类表明其主要目的是作为bean定义的源   @Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系 代码示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 .

m0_48134027的博客 1561

用Python玩转农业大数据:从Landsat遥感影像到作物产量预测实战教程

本文详细介绍了如何利用Python处理Landsat遥感影像数据,并结合土壤信息构建作物产量预测模型。从环境搭建、数据预处理到模型训练与可视化,提供了一套完整的农业大数据分析实战方案,帮助读者掌握遥感影像处理和机器学习在精准农业中的应用。

weixin_30832143的博客 397

Spring常用注解整理说明

文章目录@Configuration作用注意事项(@Configuration注解的类相关)使用方式@Bean @Configuration 作用 用来定义配置类,可以替换xml配置文件 被注解的类中含有一个或多个被@Bean注解的方法,这些方法会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean实例,初始化Spring容器 注意事项(@Configuration注解的类相关)

Dean_xiu的博客 1397

Python-OpenCV及cv2,numpy库最新安装教程[最全步骤]

安装教程目录前言OpenCV-Python安装教程报错解决cv2安装numpy安装opencv安装(附加)总结 前言 首先,我知道一些看到我的Blog的人已经在网上找了很多歪路子,现在已经火冒三丈了(我也是这样过来的hhhh),那么现在,深呼吸,跟着我的教程,不要着急,每一步都要读一遍。完整安装过程需要1个小时左右(仅供参考,本人第一次安装python花了一天(确信)) OpenCV-Python...

qq_45425286的博客 7427

SAP中成本估算没有找到工艺路线消息处理实例

在针对成品的标准成本核算处理过程中,系统中会经由设定好的策略来收集成品相关成本组成,最终计算出产成品的标准成本。关于成本组成,可以归纳为三个基本要素,料,工,费。即标准成本就是要知道,生产一件成品,需要消耗多少钱的原材料?消耗多少钱的人工?以及其它的间接消耗? 某日,接到CO同事的反馈,在用CK11N做产成品标准价格核算时,提示没有工艺路线确定,但该消息为绿灯,可以通过。基于业务上的谨慎,提出分析。 从提示可以看出问题与工艺路线有关。因为,成品工艺路线中设定有成品生产所耗工时,所以,在计算产成品标准

专注SAP应用技术文章写作,致力于拉近用户与系统间的距离; 6277

@Configuration注解详解

@Configuration注解详解 Configuration代码简介 Configuration注释类表明其主要目的是作为bean定义的源;@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系 @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Configuration { String value()

doublez的博客 4万+

北斗导航 | ILS(仪表着陆系统)、MLS(微波着陆系统)和GBAS(地基增强系统)的性能对比

最 早 的 GBAS 系 统 是 **局 域 增 强 系 统(LAAS)**,它是 1990 年由美国 Honeywell 公司 和 NASA 共 同 完 成 的 差 分 GPS(DGPS)演 变 而 来 的。1998 年,LAAS 被 ICAO 采 纳为 GBAS。2009 年 9 月 3 日 Honeywell 公 司 的GBAS 系统通过了 **CAT-I 精密进近着陆系统**的设计认证 ,而 **CAT-II 和 CAT-III 系统的研发和验证工作也正在有序的进行中**

尘世冰封的专栏 3983

@Component注解的解析

今天在写程序的时候看见一个以前没有见过的注解(@Component),在网上查找过后,经过实践,决定把它记录下来。 1、@controller 控制器(注入服务) 用于标注控制层,相当于struts中的action层 2、@service 服务(注入dao) 用于标注服务层,主要用来进行业务的逻辑处理 3、@repository(实现dao访问) 用于标...

dinghuoruo0011的博客 1449

笔试题-2023-乐鑫-数字IC设计【纯净题目版】

笔试题-2023-乐鑫-数字IC设计【纯净题目版】

w0shishabi的博客 1777

论文复现5:UMI Universal Manipulation Interface

UMI 采用手持式夹具,加上精心的界面设计,可实现便携式、低成本和信息丰富的数据收集,以进行具有挑战性的双手和动态操作演示。配备这些功能后,UMI 框架解锁了新的机器人操作功能,只需更改每个任务的训练数据,即可实现零样本可推广的动态、双手、精确和长视野行为。我们通过全面的现实世界实验展示了 UMI 的多功能性和有效性,其中通过 UMI Zeroshot 学习的策略在对不同的人类演示进行训练时可以推广到新的环境和对象。项目主页:https://umi-gripper.github.io/

github_38060285的博客 1971

@Component和@Cofiguration的区别

参考:https://www.jianshu.com/p/073d48bdeaa9

weibozhouchao的博客 575

大数据与宠物:健康监测数据分析

随着全球宠物市场规模的快速增长(2023年全球宠物产业规模已达3500亿美元),宠物健康管理需求呈现指数级上升。传统宠物医疗依赖定期体检和症状观察,存在滞后性和主观性缺陷。本文聚焦如何通过物联网(IoT)设备采集宠物生理数据(体温、心率、活动量等),利用大数据分析技术构建实时健康监测系统,实现宠物健康状态的动态评估、异常预警和疾病预测。研究范围涵盖数据采集技术、数据预处理方法、机器学习模型构建及实际应用场景落地。背景介绍:明确研究目的、目标读者及核心术语核心概念与联系。

2502_91592937的博客 1067

@configuration注解_聊聊 @Configuration 注解

点击上方蓝字关注我们!分享一个小的知识点,在一个类上添加@Configuration 注解,这个类就是配置类。提出有三个问题:如果我们没有添加这个注解程序还能不能运行?如果能是为什么?不能又是为什么?如果能,加不加@Configuration 注解有什么区别?我们先创建一个简单的程序。配置类:@Configuration@ComponentScan("com.future")publ...

weixin_39641257的博客 199

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

@query 注解的定义_聊聊 @Configuration 注解

点击上方蓝字关注我们!分享一个小的知识点,在一个类上添加@Configuration 注解,这个类就是配置类。提出有三个问题:如果我们没有添加这个注解程序还能不能运行?如果能是为什么?不能又是为什么?如果能,加不加@Configuration 注解有什么区别?我们先创建一个简单的程序。配置类:@Configuration@ComponentScan("com.future")publ...

weixin_36378771的博客 176

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

spring原理之@Conditional与@Configuration

spring的心得体会

huanleshidai的博客 545

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Spring核心:@Configuration注解详解

在配置类中,你可以使用@Bean注解在方法上,该方法返回的对象将被 Spring 容器注册为一个 Bean。​​传统 XML 方式:​​<beans></beans>​​现代方式:​​@Bean​​核心配置​​:用于定义应用的核心配置、数据源、第三方库集成等无法使用自动注册的 Bean。​​替代 XML​​:是现代 Spring 和 Spring Boot 应用中​​首选​​的配置方式,完全取代了繁琐的 XML 配置。​​与@Bean搭档​是舞台,@Bean方法是舞台上的演员,二者密不可分。

bemyrunningdog 556

聊聊Spring家族中的那几百个注解

本文我们来梳理一下Spring的那些注解,如下图所示,大概从几方面列出了Spring的一些注解:如果此图看不清楚也没事,请运行下面的代码输出所有的结果。Spring目前的趋势是使用注解结合Java代码而不是配置来定义行为、属性、功能、规则和扩展点,因此梳理注解也是梳理Spring功能点的很好的方式,全面的梳理可以补足我们知识点的漏洞。查找所有注解首先,我们来创建一个项目,使用SPRING INIT...

weixin_34268753的博客 247

聊聊@AutoConfiguration,@AutoConfigureBefore,@AutoConfigureAfter,@AutoConfigureOrder

对@AutoConfiguration的研究,以及注解@AutoConfigureBefore,@AutoConfigureAfter,@AutoConfigureOrder生效问题``以上就是今天要讲的内容。

weixin_42040314的博客 2230

五大类注解的使用:

那么为什么需要怎么多的类注解也是相同的原因,就是让程序员看到类注解之后,就能直接了解当前类 的⽤途,⽐如: @Controller:表示的是业务逻辑层;那么给大家举个例子吧,就像我们生活中的车牌号一样,每个地区都有不同的车牌前缀,这样做的好处除了可以节约号码之外,更重要的作 ⽤是可以直观的标识⼀辆⻋的归属地;如果首字母是大写,第二个字母是小写,那么Bean的名称就是类名小写,如果不满足上述条件,那么Bean的名称就是原类名。那么就会有人有疑问了,那明明一样,为什么还需要五个而不是一个呢?

weixin_46198164的博客 105

Spring Boot 中 @EnableXXX 注解的驱动逻辑

点击上方蓝色“程序猿DD”,选择“设为星标”回复“资源”获取独家整理的学习资料!作者 |温安适来源 |https://juejin.im/post/5efdd689e51d4534a...

程序猿DD 789

肝了一周总结的SpringBoot常用注解大全,一目了然!

这些SpringBoot注解基本都是我平时做项目常用的注解,在我的电商实战项目mall中基本都用到了,这里做了一番整理归纳,希望对大家有所帮助!

BASK2311的博客 1945

聊聊Spring中的ConfigurationClassPostProcessor

 之前有讲到过在Spring中有各种各样的BeanFantoryPostProcessor后置处理器,在这些后置处理器中有一个对于Spring使用java Config起着至关重要的后置处理器,他就是ConfigurationClassPostProcessor,因为通过他的一个方法postProcessBeanDefinitionRegistry会进行类的扫描以及注册,在这个方法中对于配置类进行...

TankyZhang的博客 2759

@JsonProperty 和 @JSONField注解的使用方法及其异同?

本文介绍了在Java开发中通过注解解决JSON序列化与反序列化字段映射问题的方案。主要对比了Jackson的@JsonProperty和Fastjson的@JSONField两个注解的使用方法,包括字段重命名、日期格式化和控制序列化方向等功能。通过实体类Student的代码示例,展示了不加注解和使用不同注解时的序列化效果差异。文章还提供了Fastjson和Jackson的全局映射配置方案,并解释了实体类实现Serializable接口的作用和必要性。最后建议开发中为实体类添加序列化版本号以保证兼容性。

m0_70325779的博客 3231

耗时一周,总结出了SpringBoot常用注解大全。让你一目了然。

这些SpringBoot注解基本都是我平时做项目常用的注解,在我的电商实战项目mall中基本都用到了,这里做了一番整理归纳,希望对大家有所帮助!

Java技术攻略的博客 276

Spring全注解开发进阶:原理、实践与常见陷阱解析

注解驱动开发已成为Java后端工程的主流范式,它源于JDK 5的元数据机制,却在Spring Boot的自动配置与约定大于配置理念下得以普及。其核心原理是将传统XML中的组件定义、依赖关系与生命周期管理,通过@Configuration、@ComponentScan等注解内聚到代码中,配合@Autowired构造器注入与@Transactional声明式事务,实现类型安全的装配与事务边界控制。这种模式显著提升了配置的可读性与重构效率,降低了多文件维护的上下文切换成本,特别适合微服务与云原生下的快速迭代场景。

weixin_29206669的博客 285
上一篇: 粗浅讲讲 DI 和 IOC
下一篇: Spring 循环依赖
Future_LL
博客等级 码龄9年 215粉丝 255原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值