Spring 自动配置 condition

目录

前言

1. 自定义condition加载bean

 1.1. 自定义一个condition注解

1.2. 实现自定义注解对应的实现类 

 1.3. 使用如上注解

1.4. 使用Spring上下文获取一下改bean

 2. 我们来看看Spring是如何加载redisTemplate的。

 2.1. 找到Spring的autoconfigure的jar包,我们从中可以看到有很多对应的condition注解及他们的实现类:​编辑

2.2. 要初始化出来redisTemplate出来有很多条件,其中一个就是要有redis对应的依赖中的字节码文件。​编辑

3. Spring自动切换Web服务器(Tomcat/Netty/Jetty ...)

总结Spring Condition


前言

 我们都知道,当我们创建一个基于Spring的项目的时候,我们都需要在Applicaiton启动引导类上加上@ComponentScan("com.acom.springdemo.*")注解,用于引导Spring指定扫描范围。如果我们不写的话Spring默认扫描的就只有Application启动类所在的根目录及其子目录。Spring为什么呢一定要指定扫描范围。试想一下我们有一个大项目,它依赖了很多的jar包,拿到要Spring启动时都将他们扫描一次,Spring又如何知道当前项目有哪些jar包,如果把所有的jar都扫描一次,很多jar是没有bean的,是不是会引起Spring项目启动很慢等问题。

有的时候我们需要引用外部jar包如Redis,显然这个外部jar包不在我们@ComponentScan所指定的范围内,那么Spring是如何自动加载它的呢?今天我们就来学些Spring condition在其中的作用。

1. 自定义condition加载bean

 假设我们有这样一个需求,我们自定义一个user类的bean,但是这个bean需要在我们的pom中引用了Jedis和FastJson这两个jar包之后才能加载该bean,否则不能加载。
因此我们就需要自定义一个codition 用于限制bean的加载。
自定义bean的示意图如下:

 1.1. 自定义一个condition注解

package com.mycompany.condition;

import org.springframework.context.annotation.Conditional;
import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ClassConditionImpl.class)
public @interface MyConditionOnClass {
    String[] value();
}

自定义一个condition注解类MyConditionOnClass,其中@Conditional(ClassConditionImpl.class)是说明当前注解是一个Condition注解,且该注解的具体实现类是ClassConditionImpl.class。这里我们需要明白的是,注解的本质其实就是一个标记,标记在方法或类上等,标记了之后它的实现类才能知道哪些方法需要做对应的处理,因而注解本身是不包含什么逻辑的,它只是一个标记。

1.2. 实现自定义注解对应的实现类 

public class ClassConditionImpl implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        Map<String, Object> map = metadata.getAnnotationAttributes(MyConditionOnClass.class.getName());
        String[] value = (String[]) map.get("value");
        try {
            for (String className : value){
                Class<?> cls = Class.forName(className);
            }
            return true;
        }catch (ClassNotFoundException ex){
            return false;
        }

    }
}

自定义注解的实现类必须实现Spring的 Condition接口,因为Spring需要通过该接口传入Spring的上下文,以及自定义注解定义的参数信息,以便我们的实现类使用。详细如下:

  • ConditionContext context:
    上下文对象。用于获取环境,IOC容器,ClassLoader对象等。
  • AnnotatedTypeMetadata metadata
    注解的元对象,可以用于获取注解定义的元属性值

 1.3. 使用如上注解

@Configuration
public class UserConfig {

    @Bean
    @MyConditionOnClass({"redis.clients.jedis.Jedis","com.alibaba.fastjson.JSON"})
    public User user(){
        return new User();
    }
}

1.4. 使用Spring上下文获取一下改bean

@SpringBootApplication
@ComponentScan
public class SpringbootConditionApplication {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionApplication.class,args);

        Object user = context.getBean("user");
        System.out.println(user);
    }
}

测试当我们没有引用如上的jar包时:
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'user' available
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:874)


当我们引用了如上的jar包时:
com.mycompany.domain.User@7c71c889
 

 2. 我们来看看Spring是如何加载redisTemplate的。

 2.1. 找到Spring的autoconfigure的jar包,我们从中可以看到有很多对应的condition注解及他们的实现类:

2.2. 要初始化出来redisTemplate出来有很多条件,其中一个就是要有redis对应的依赖中的字节码文件。

3. Spring自动切换Web服务器(Tomcat/Netty/Jetty ...)

我们都知道基于Spring的项目默认使用的是Tomcat web服务器。那么我们如何切换为其他web服务器呢?我们可以看到对应服务器的加载也是基于@ConditionalOnClass注解的。

所以如果我们要不使用Tomcat而是要使用其他的web服务器,我们只需要排除Tomcat然后再加载对应的web服务器依赖就可以了
 

       <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-tomcat</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

启动日志

2024-06-09 18:06:58.223  INFO 15600 --- [           main] o.s.b.web.embedded.jetty.JettyWebServer  : Jetty started on port(s) 8080 (http/1.1) with context path '/'
2024-06-09 18:06:58.231  INFO 15600 --- [           main] c.m.SpringbootConditionApplication       : Started SpringbootConditionApplication in 3.385 seconds (JVM running for 3.972)

 

总结Spring Condition

Spring Condition的作用主要是根据特定条件来控制Bean的创建和注册行为。这种机制使得Spring框架在进行依赖注入时能够更加灵活和智能化。具体来说,其作用可以归纳为以下几点:

  • 条件化Bean的注册:通过@Conditional注解,可以指定Bean注册到Spring IOC容器中的条件。只有当这些条件满足时,相应的Bean才会被创建和注册。这种动态注册Bean的方式提高了Spring应用的灵活性和可配置性。
  • 实现自动化配置:Spring Condition机制常用于Spring Boot等框架中,以实现自动化配置。根据应用环境的不同,例如开发环境、测试环境和生产环境,可以自动地选择性地注册Bean,从而简化了配置工作。
  • 整合环境和配置:通过ConditionContext对象,可以获取到当前的环境信息,如操作系统类型、Java版本等。这使得我们可以根据这些环境信息来动态地决定是否注册某个Bean。
  • 扩展性和灵活性:由于Condition是一个函数式接口,开发者可以自定义实现类来重写matches()方法,以定义自己的条件判断逻辑。这种设计使得Spring Condition具有极高的扩展性和灵活性。

总的来说,Spring Condition的作用在于提供了一种根据特定条件动态注册Bean的机制,使得Spring框架在进行依赖注入时能够根据实际情况做出更智能的决策。这种机制在Spring Boot等框架中得到了广泛应用,极大地简化了应用的配置和部署工作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/695378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

超详解——python数字和运算——基础篇

目录 1.位运算 2. 常用内置函数/模块 math模块&#xff1a; random模块&#xff1a; decimal模块&#xff1a; 3.内置函数&#xff1a; 总结&#xff1a; 1.位运算 位运算是对整数在内存中的二进制表示进行操作。Python支持以下常见的位运算符&#xff1a; 按位与&…

Fedora的远程桌面

要在 Fedora 40 上开启远程桌面功能。 首先&#xff0c;要确保已安装 gnome-remote-desktop 和 vino 包。 这些软件包通常默认安装在 Fedora 的 GNOME 桌面环境中。 可以按照以下步骤操作&#xff1a; 1、判断电脑是否安装了 gnome-remote-desktop 和 vino 包: tomfedora:…

Web后端开发(请求-数组集合、日期、JSON参数)(三)

数组参数&#xff1a;请求参数名与形参数组名称相同且请求参数为多个&#xff0c;定义数组类型形参即可接收参数 RequestMapping("/arrayParam") public String arrayParam(String[] hobby){System.out.println(Arrays.toString(hobby));return "OK"; } …

短剧小程序剧场短剧APP定制开发付费短剧之为什么自建?

在当今数字时代&#xff0c;拥有一个属于自己的小剧场短剧影视小程序不仅是追求创作梦想的新途径&#xff0c;也是与观众建立紧密联系的有效方式。这种新兴的平台为创作者提供了前所未有的自由和机会&#xff0c;使他们能够直接与广大观众交流和分享作品。 1、源码分享的重要性…

使用GPT-soVITS再4060下2小时训练声音模型以及处理断句带来的声音模糊问题

B站UP主视频 感谢UP主“白菜工厂1145号员工”的“熟肉”&#xff0c;我这篇笔记就不展示整一个训练和推理流程&#xff0c;重点写的4060该注意的一些事项。如何解决断句模糊的问题&#xff0c;在本篇笔记的最末尾。 相关连接&#xff1a; 原项目github UP主的说明文档 1、训…

【冒泡排序】

冒泡排序的核心思想就是&#xff1a;两两相邻的元素进行比较 如果不满足顺序就交换&#xff0c;满足顺序就找下一对 //⽅法1 void bubble_sort(int arr[], int sz)//参数接收数组元素个数 {int i 0;for(i0; i<sz-1; i){int j 0;for(j0; j<sz-i-1; j){if(arr[j] > a…

Java学习 - MyBatis - 初识MyBatis

前言 什么是持久化 持久化是将程序数据在持久状态和瞬时状态间转换的机制&#xff0c;将数据保存到可永久保存的存储设备中。最常见的就是将内存中的对象存储在数据库中&#xff0c;或者存在磁盘文件、XML 数据文件中等等。其中&#xff0c;文件 IO 属于持久化机制&#xff0…

C++11新特性【上】(统一的列表初始化、auto、decltype、右值引用、万能引用、完美转发)

一、C11简介 在2003年C标准委员会曾经提交了一份技术勘误表(简称TC1)&#xff0c;使得C03这个名字已经取代了 C98称为C11之前的最新C标准名称。不过由于C03(TC1)主要是对C98标准中的漏洞 进行修复&#xff0c;语言的核心部分则没有改动&#xff0c;因此人们习惯性的把两个标准合…

攻防世界---misc---BotW-

1、下载附件是一张图片 2、查看图片属性&#xff0c;用winhex分析&#xff0c;没有发现奇怪的地方&#xff0c;用binwalk&#xff0c;接着使用foremost 3、得到两张图片&#xff0c;一张是原图&#xff0c;一张是特殊的字符 4、经过查阅资料得知&#xff0c;这是希卡文字&#…

《庆余年》角色穿越高考:谁将笑傲现代考场?

一、引言 《庆余年》是一部以古代中国为背景的权谋小说&#xff0c;其角色们各具特色&#xff0c;聪明才智、武艺高强、忠诚耿直等特质使得他们在古代世界中游刃有余。然而&#xff0c;如果我们将这些角色置于现代高考的背景之下&#xff0c;他们将如何面对这一挑战&#xff1…

Llama模型家族之Stanford NLP ReFT源代码探索 (三)reft_model.py代码解析

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

【题解】—— LeetCode一周小结23

&#x1f31f;欢迎来到 我的博客 —— 探索技术的无限可能&#xff01; &#x1f31f;博客的简介&#xff08;文章目录&#xff09; 【题解】—— 每日一道题目栏 上接&#xff1a;【题解】—— LeetCode一周小结22 3.分糖果 II 题目链接&#xff1a;1103. 分糖果 II 排排坐…

Switch 之 H3C S5500

System # system view <H3C> system‐view [H3C] quit <H3C># display version [H3C]display version H3C Comware Software, Version 7.1.045, Release 3116# configuration save <H3C> save <H3C> display current‐configuration # factory reset …

Elasticsearch 认证模拟题 - 17

这两道题目非常具有代表性&#xff0c;分别是跨集群复制和跨集群检索&#xff0c;需要相应的 许可 这里在虚拟机上搭建集群完成这两道题目&#xff0c;这里补充一下 elasticsearch 和 kibana 的配置文件 # elasticsearch.yml cluster.name: cluster2 node.name: cluster2-node…

4.大模型微调技术LoRA

大模型低秩适配(LoRA)技术 现有PEFT 方法的局限与挑战 Adapter方法,通过增加模型深度而额外增加了模型推理延时。Prompt Tuning、Prefix Tuning、P-Tuning等方法中的提示较难训练,同时缩短了模型可用的序列长度。往往难以同时实现高效率和高质量,效果通常不及完全微调(f…

【成品设计】基于单片机的智慧交通控制系统设计

《基于单片机的智慧交通控制系统设计》 所需器件&#xff1a; STM32最小系统板。按键模块。红黄绿LED灯柱。距离传感器。OLED屏幕。语音识别模块。 整体功能&#xff1a; 本文介绍了一种基于单片机的智慧交通控制系统设计。该系统集成了多种传感器、控制器和执行器&#xf…

[Llama3] ReAct Prompt 测试实验

ReAct 是一种 LLM 提示和结果处理方法&#xff0c;结合了推理、行动计划和知识源整合&#xff0c;使 LLM 超越其语言模型&#xff0c;并在预测中使用来自现实世界的信息。 ReAct 是推理和行动的结合。 介绍 ReAct 的论文表明它比思维链提示更好。与后者不同的是&#xff0c;Re…

【数据结构】【版本1.0】【线性时代】——顺序表

快乐的流畅&#xff1a;个人主页 个人专栏&#xff1a;《算法神殿》《数据结构世界》《进击的C》 远方有一堆篝火&#xff0c;在为久候之人燃烧&#xff01; 文章目录 引言一、顺序表的概念1.1 最基础的数据结构&#xff1a;数组1.2 数组与顺序表的区别 二、静态顺序表三、动态…

基于STM32F030设计的多点温度采集系统(BC26+OneNet)

一、项目背景 随着物联网技术的迅猛发展&#xff0c;越来越多的智能设备应运而生&#xff0c;而温度采集系统是其中重要的一类。在现代工业和家庭生活中&#xff0c;温度对于生产、居住和储存等过程的控制有着非常重要的作用。因此&#xff0c;准确地采集环境温度数据并进行处…

Ubuntu基础 - 常用命令

目录 一.打开终端 1.快捷键 2.右键桌面 3.应用程序管理 二. 常用命令 1. ls命令 2. cd 命令 3. pwd 命令 4. mkdir 命令 5. rm 命令 和 rmdir 命令 6. mv 命令 7. cp 命令 8. touch 9. more 命令 less 命令 10. echo > 前言:大家好,这是一篇ubuntu常用的基…