spring boot 系列之六:@Conditional和spring boot的自动配置

我们知道,spring boot自动配置功能可以根据不同情况来决定spring配置应该用哪个,不应该用哪个,举个例子:

  • Spring的JdbcTemplate是不是在Classpath里面?如果是,并且DataSource也存在,就自动配置一个JdbcTemplate的Bean
  • Thymeleaf是不是在Classpath里面?如果是,则自动配置Thymeleaf的模板解析器、视图解析器、模板引擎

那个这个是怎么实现的呢?原因就在于它利用了Spring的条件化配置,条件化配置允许配置存在于应用中,但是在满足某些特定条件前会忽略这些配置。

要实现条件化配置我们要用到@Conditional条件化注解。接下来写个小例子来感受下@Conditional是怎么工作的。

一、@Conditional小例子

我们知道在windows下显示列表的命令是dir,而在linux系统下显示列表的命令是ls,基于条件配置,我们可以实现在不同的操作系统下返回不同的值。

  1. 判断条件定义

    1. )windows下的判定条件

      /**
       * 实现spring 的Condition接口,并且重写matches()方法,如果操作系统是windows就返回true
       *
       */
      public class WindowsCondition implements Condition{
      
          @Override
          public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      
              return context.getEnvironment().getProperty("os.name").contains("Windows");
          }
      
      }
    2. )linux下的判定条件

      /**
       * 实现spring 的Condition接口,并且重写matches()方法,如果操作系统是linux就返回true
       *
       */
      public class LinuxCondition implements Condition{
      
          @Override
          public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
      
              return context.getEnvironment().getProperty("os.name").contains("Linux");
          }
      
      }
  2. 不同系统下的Bean的类
    1. )接口

      public interface ListService {
      
          public String showListLine();
      }
    2. )windows下的Bean类

      public class WindowsListService implements ListService{
      
          @Override
          public String showListLine() {
              return "dir";
          }
      
      }
    3. )linux下的Bean的类

      public class LinuxListService implements ListService{
      
          @Override
          public String showListLine() {
              return "ls";
          }
      
      }
  3. 配置类

    @Configuration
    public class ConditionConfig {
    
        /**
         * 通过@Conditional 注解,符合windows条件就返回WindowsListService实例
         *
         */
        @Bean
        @Conditional(WindowsCondition.class)
        public ListService windonwsListService() {
            return new WindowsListService();
        }
    
        /**
         * 通过@Conditional 注解,符合linux条件就返回LinuxListService实例
         *
         */
        @Bean
        @Conditional(LinuxCondition.class)
        public ListService linuxListService() {
            return new LinuxListService();
        }
    }
  4. 测试类

    public class ConditionTest {
    
        public static void main(String[] args) {
    
            AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
            ListService listService = context.getBean(ListService.class);
            System.out
                    .println(context.getEnvironment().getProperty("os.name") + " 系统下的列表命令为: " + listService.showListLine());
        }
    }
  5. 运行测试类,由于我的是windows7 系统,因此结果是

    Windows 7 系统下的列表命令为: dir

    如果你的是linux系统,则结果就会是

    Linux 系统下的列表命令为: ls

二、spring boot 的条件化配置

在spring boot项目中会存在一个名为spring-boot-autoconfigure的jar包

条件化配置就是在这个jar里面实现的,它用到了如下的条件化注解,这些注解都是以@Conditional开头的:

接下来我们看个源码的列子:

以JdbcTemplateAutoConfiguration为例,它里面有这段代码:

@Bean
    @Primary
    @ConditionalOnMissingBean(JdbcOperations.class)
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(this.dataSource);
    }

只有在不存在JdbcOperations(如果查看JdbcTemplate的源码,你会发现JdbcTemplate类实现了JdbcOperations接口)实例的时候,才会初始化一个JdbcTemplate 的Bean。

基于以上内容,我们就可以阅读自动配置相关的源码了。

原文地址:https://www.cnblogs.com/sam-uncle/p/9104256.html

时间: 2024-10-13 19:25:59

spring boot 系列之六:@Conditional和spring boot的自动配置的相关文章

spring boot系列(五)spring boot 配置spring data jpa (查询方法)

接着上面spring boot系列(四)spring boot 配置spring data jpa 保存修改方法继续做查询的测试: 1 创建UserInfo实体类,代码和https://www.cnblogs.com/kxm87/p/9273555.html中的一样. 2 创建数据库操作类相当于dao层,主要创建一个接口UserRepository,继承JpaRepository接口即可.本代码中主要都是自定义方法. 使用findXX 或者countXX(这两个不用编写sql,jpa会自动生成)

Spring Boot系列(一) Spring Boot介绍和基础POM文件

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. Spring Boot的特点 1. 创建独立的Spring应用程序 2. 直接嵌入Tomcat,Jetty或Undertow,无需部署WAR文件 3. 提供推荐的基础POM

[Spring Batch 系列] 第一节 初识 Spring Batch

距离开始使用 Spring Batch 有一段时间了,一直没有时间整理,现在项目即将完结,整理下这段时间学习和使用经历. 官网地址:http://projects.spring.io/spring-batch/ 一.定义与特点 A lightweight, comprehensive batch framework designed to enable the development of robust batch applications vital for the daily operati

[Spring实战系列](5)Spring应用上下文

下面是Spring-Hello-world项目的运行代码: package com.sjf.bean; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 测试类 * @author sjf0115 * */ public class Test { private static

Spring学习系列(四)——Spring中的国际化

1.Java中的国际化国际化(Internationalization)简称 i18n,简单来说就是不同国家/地区/语言的用户,访问同一个程序,得到对应的本地化资源. 首先要确定国家/地区/语言(Locale类) 然后根据不同的Locale获取对应的本地化资源(locale敏感的). 而本地化资源相关的主要有两种:ResourceBundle和Format抽象类的子类.①Jdk为ResourceBundle抽象类提供了两个子类(ListResourceBundle和PropertyResourc

Spring Boot2 系列教程(四)理解Spring Boot 配置文件 application.properties

在 Spring Boot 中,配置文件有两种不同的格式,一个是 properties ,另一个是 yaml . 虽然 properties 文件比较常见,但是相对于 properties 而言,yaml 更加简洁明了,而且使用的场景也更多,很多开源项目都是使用 yaml 进行配置(例如 Hexo).除了简洁,yaml 还有另外一个特点,就是 yaml 中的数据是有序的,properties 中的数据是无序的,在一些需要路径匹配的配置中,顺序就显得尤为重要(例如我们在 Spring Cloud

Spring Boot系列教程七:Spring boot集成MyBatis

一.创建项目 项目名称为 "springboot_mybatis_demo",创建过程中勾选 "Web","MyBatis","MySQL",第一次创建Maven需要下载依赖包(耐心等待) 二.实现 2.1创建User类 1 package com.woniu.bean; 2 3 4 public class User { 5 private long id; 6 private String name; 7 private

Spring Boot2 系列教程 (七) | 使用 Spring Data JPA 访问 Mysql

前言 如题,今天介绍 Spring Data JPA 的使用. 什么是 Spring Data JPA 在介绍 Spring Data JPA 之前,首先介绍 Hibernate . Hibernate 使用 O/R 映射 (Object-Relation Mapping) 技术实现数据访问, O/R 映射即将领域模型类与数据库的表进行映射,通过程序操作对象而实现表数据操作的能力,让数据访问操作无需关注数据库相关技术. Hibernate 主导了 EJB 3.0 的 JPA 规范, JPA 即

[Spring实战系列](8)Spring注入方式之setter注入

通常,JavaBean 的属性是私有的,同时拥有一组存取器方法,以setXXX() 和getXXX() 形式存在.Spring 可以借助属性的set方法来配置属性的值,以实现setter方式的注入. 1. 注入简单值 在Spring 中我们可以使用<property> 元素配置Bean 的属性.<property>在许多方面都与<constructor-arg> 类似,只不过一个是通过构造参数来注入值,另一个是通过调用属性的setter 方法来注入值. 举例说明,让我们