SpringBoot自动配置-Condition/切换内置服务器

这篇具有很好参考价值的文章主要介绍了SpringBoot自动配置-Condition/切换内置服务器。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、Condition注解

1.情景一:判断指定文件是否存在

需求:在Spring的IoC容器中有一个User的bean,要求:
导入Jedis坐标后,加载该Bean,没有导入,则不加载。

实现:

项目结构:
SpringBoot自动配置-Condition/切换内置服务器,spring boot,java,后端

(1)创建User类:

package mainDir.domain;


public class User {
    private String name;
    private int age;
    
    //getter & setter & toString
    ......
}

(2)创建bean定义的源UserConfig:

package mainDir.config;

import mainDir.condition.ClassCondition;
import mainDir.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

//@Configuration类允许通过调用同一类中的其他@Bean方法来定义bean之间的依赖关系
@Configuration
public class UserConfig {
    
    //@Bean注解用于告诉该方法,产生一个Bean对象,然后这个Bean对象交给Spring管理。 
    //产生这个Bean对象的方法Spring只会调用一次,随后这个Spring将会将这个Bean对象
    //放在自己的IOC容器中
    @Bean
    @Conditional(ClassCondition.class)
    public User user(){
        //instantiate, configure and return bean
        //通过这个方法生成一个名为user的Bean
        return new User();
    }
}

如果你不清楚@Configuration标签和@Bean注解的作用,可以参考下面的博客:
@Configuration注解详解_技术宅丶拾年的博客-CSDN博客
大白话讲解Spring的@bean注解 - 知乎 (zhihu.com)

接下来我们来关注@Conditional注解的使用:

首先,在这个注解中,我们要传入一个静态类ClassCondition(这个类名可以自定义),在这个类中编写判断user()方法是否执行的条件

(3)编写ClassCondition类进行测试:

package mainDir.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;

public class ClassCondition implements Condition {
    @Override
    public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
        return false;
    }
}

启动类:(测试是否获取到bean)

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        //返回Spring的IoC容器
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
        //获取bean -- user
        User user = context.getBean("user", User.class);
        System.out.println(user);
    }
}

注意你引入的Condition接口是否正确:org.springframework.context.annotation.Condition。
在上面的代码中,如果直接返回false,那么这个方法将不会被调用。同理,你在进行测试的时候如果执行context.getBean("user")时,这个语句将会报错:No bean named 'user' available

在进行判断前,我们在路径中加入Jedis依赖:

        <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
        </dependency>

接下来修改判断条件文件ClassCondition:

public class ClassCondition implements Condition {
    
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        boolean flag = true;
        try {
            //思路:判断redis.clents.jedis.Jedis.class文件是否存在
            Class<?> cls = Class.forName("redis.clients.jedis.Jedis");
        }catch (ClassNotFoundException e){
            flag = false;
        }
        return flag;
    }
}

此时,你可以修改这个文件,观察@Conditional注解下的bean能否成功创建。

2.情景二:进行动态判断

需求:现在需要在书写UserConfig.class时再向condition文件中传入要进行判断的参数(而非直接写在定义好的ClassCondition类中)。

(1)创建自己的注解@ConditionOnClass:

package com.test.condition;

import org.springframework.context.annotation.Conditional;

import java.lang.annotation.*;

//在自定义注解上添加三个原注解
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ClassCondition.class)
public @interface ConditionOnClass {
    String[] value();
}

注意这个类上有四个注解,前三个注解可以在Conditional类的定义中找到。
第四个注解@Conditional(ClassCondtion.class)则指向你之前定义的条件类。这个注解中写入你进行判断的方法。

(2)ClassCondition类:

package com.test.condition;

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;

import java.util.Map;

public class ClassCondition implements Condition {
    /***
     * matches方法的两个参数能够帮助我们动态地获取需要进行判断的信息
     * @param context 上下文对象。用于获取环境、IoC容器、ClassLoader对象等
     * @param metadata 注解元对象。可以用于获取注解定义的属性值
     * @return
     */
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        //获取环境信息(注意导入的是springframework包下的类)
        //Environment environment = context.getEnvironment();
        //还可以通过环境获取配置类
        //environment.getProperty();
        
        //通过注解属性value指定的坐标后创建bean
        
        //获取注解属性值value
        Map<String, Object> map = metadata.getAnnotationAttributes(ConditionOnClass.class.getName());
        //获取"value"对应的值(即在@ConditionOnClass()自定义注解中传入的值)
        String value[] = (String[]) map.get("value");
        
        boolean flag = true;
        try {
            //遍历value数组的值,即各级路径,若存在一个路径对应不上,则说明文件不存在
            for (String className : value){
                Class<?> cls = Class.forName(className);
            }
        }catch (ClassNotFoundException e){
            flag = false;
        }
        return flag;
    }
}

在这个类中,写入你要进行判断的条件。与情景一不同的是,你将获取到由自定义注解ConditionOnClass传入的参数String value[]。可以在metadata属性中使用getAnnotationAttributes方法来进行获取。

(3)接下来,就可以使用启动类进行测试,和情景一相同。
 

小结

自定义条件:自定义类实现Condition接口,重写matches方法,在matches方法中进行逻辑判断,返回boolean值。matches方法有两个参数:

context:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
metaData:元数组对象,用于获取注解属性

判断条件:初始化bean时,使用@Condition(条件类.class)注解

SpringBoot提供的常用条件注解

@ConditionalOnProperty:当配置文件中(application.yml)指定的属性和对应的值存在,才会创建bean。 

@ConditionalOnClass:判断环境中是否有对应字节码文件才初始化bean。

@ConditionalOnMissingBean:判断环境中有没有对应bean才初始化bean。

二、切换内置服务器

在依赖文件的web包下,可以找到一个叫做embedded的文件夹,里面有包含Tomcat在内的4种内置服务器:

SpringBoot自动配置-Condition/切换内置服务器,spring boot,java,后端

接下来,我们找到文件夹中的配置类EmbeddedWebServerFactoryCustomizerAutoConfiguration:

SpringBoot自动配置-Condition/切换内置服务器,spring boot,java,后端 在这个类中,我们可以看到刚刚学到的@Condition注解。@ConditionalOnClass判断环境中是否有相应字节码文件,才初始化bean。

接下来,我们看spring-boot-starter-web中的依赖:
SpringBoot自动配置-Condition/切换内置服务器,spring boot,java,后端现在我们来排除tomcat的依赖: 点击tomcat,右键Exclude,在pom.xml文件中观察变化:

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

可以发现,现在tomcat的依赖已经被排除。接下来引入对jetty的依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

现在重启服务器,观察控制台可以发现,当前启动的服务器为jetty:
SpringBoot自动配置-Condition/切换内置服务器,spring boot,java,后端

参考资源:
【黑马程序员SpringBoot教程,6小时快速入门Java微服务架构Spring Boot】 https://www.bilibili.com/video/BV1Lq4y1J77x/?p=22&share_source=copy_web&vd_source=97444cc205d3d3ef369bafb60cf90ca0文章来源地址https://www.toymoban.com/news/detail-832830.html

到了这里,关于SpringBoot自动配置-Condition/切换内置服务器的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • springboot配置swagger报错Cannot invoke “org.springframework.web.servlet.mvc.condition.......”

    springboot配置swagger时报错,spring boot使用版本为2.7.16或3.1.5,JDK17,项目启动报错,项目使用swagger 3.0. 具体报错信息如下: swagger导入依赖如下: 解决方案:在application.yml中引入以下配置: 另外,因为版本不同,访问路径改变和访问的文件名也与之前版本不一致! 直接访问h

    2024年01月22日
    浏览(39)
  • 云服务器使用jenkins+docker自动化部署SpringBoot项目

    docker 安装jenkins,就这一步都恶心死了 //拉取镜像,踩了很多坑,用其它版本的镜像插件一直安装失败,最后用的是lts版本(基础版) 用其它版本要么是连不上插件的下载地址,要么是插件下载不成功  docker pull jenkins/jenkins:lts  部署 docker run --user root -d -p 10240:8080 -p 10241:50

    2024年02月01日
    浏览(42)
  • 【Linux】使用Jenkins + svn + springboot自动构建jar包并自动打包在服务器上运行

    👨‍🎓 博主简介   🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊 交流社区: 运维交流社区 欢迎大家的加入! 🐋 希望大家多多支持,我们一起进步!😄 🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏

    2024年04月26日
    浏览(29)
  • iTerm2 自动连接服务器配置

    iTerm2 自动连接服务器配置 创建ssh_conf.sh配置文件 编辑配置文件内容 菜单栏打开 Profiles,然后点 Edit Profiles 点击加号添加一个新的 Profile,在 Command 中写上这个命令,路径用你自己配置文件的路径 配置结束,下面是常用的命令 文件上传远程服务器root下 后台运行 查看正在运行

    2024年02月06日
    浏览(37)
  • Gitee+Jenkins(docker版)自动推送并部署Springboot项目到远程服务器

    如果要参考gitlab配置请参考Gitlab+Webhook自动推送并更新Springboot项目 Gitlab的配置部分 Jenkins服务器(Centos7.6): docker安装的jenkins,参考Jenkins(docker安装)部署Springboot项目 JDK1.8 Maven3.6.3 注意docker安装的jenkins,而且是较新的版本,所以jenkins容器内的java版本是11的,而我的项目是基于JDK1.8的

    2024年02月13日
    浏览(32)
  • “配置DHCP服务器和DHCP中继的网络自动配置实验“

    \\\"配置DHCP服务器和DHCP中继的网络自动配置实验\\\"   【实验目的】 部署DHCP服务器。 熟悉DHCP中继的配置方法。 验证拓扑。 【实验拓扑】 实验拓扑如图所示。 设备参数如下表所示。 设备 接口 IP地址 子网掩码 默认网关 DHCPSERVE S0/3/0 192.168.10.1 255.255.255.0 N/A R2 S0/3/0 192.168.10.2 255.

    2024年02月08日
    浏览(41)
  • 36、springboot --- 对 tomcat服务器 和 undertow服务器 配置访客日志

    访客日志: Web服务器可以将所有访问用户的记录都以日志的形式记录下来,主要就是记录来自哪个IP的用户、在哪个时间点、访问了哪个资源。 pattern: %t 访问时间 %a 访问用户的ip “%r” 访问的方式和地址 %s 使用的协议 (%D ms) 访问后的响应 代码演示: 这是用 tomcat 来设置 访

    2024年02月10日
    浏览(36)
  • nodejs配置express服务器,运行自动打开浏览器

    查看专栏目录 Network 灰鸽宝典专栏主要关注服务器的配置,前后端开发环境的配置,编辑器的配置,网络服务的配置,网络命令的应用与配置,windows常见问题的解决等。 作为前端开发的项目,有的时候打包完后就想在本地测试是什么样子的,另外一些如cesium等程序,需要在

    2024年02月04日
    浏览(41)
  • DNS:自动化配置 主/从/缓存 DNS服务器

    学习遇到 DNS 自动化部署的一个 Ansible 剧本,这里分享给小伙 部署使用 Bind9 ,包括主从 DNS 构建,缓存 DNS 构建,缓存使用 unbound 剧本相对简单 理解不足小伙伴帮忙指正 对每个人而言,真正的职责只有一个:找到自我。然后在心中坚守其一生,全心全意,永不停息。所有其它

    2024年02月13日
    浏览(31)
  • Ubuntu20.04.5配置nfs服务器并自动挂载

    两台Ubuntu20.04.5版本的操作系统 分别当作一台服务器,一台客户机 1.服务器端(主机名我的是ceph01) 1.1安装nfs服务 apt install nfs-kernel-server 1.2 查看nfs版本 cat /proc/fs/nfsd/versions 安装完成后,NFS 服务将会自动启动,默认在Ubuntu 20.04上NFS2 被禁用,NFS3和NFS4以上可以使用。 查看NFS的版

    2024年02月06日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包