Spring条件注解@Conditional示例详解

前言

@Conditional是Spring4新提供的注解,它的作用是根据某个条件创建特定的Bean,通过实现Condition接口,并重写matches接口来构造判断条件。总的来说,就是根据特定条件来控制Bean的创建行为,这样我们可以利用这个特性进行一些自动的配置。

本文将分为三大部分,@Conditional源码的介绍、Condition的使用示例和@Conditional的扩展注解的介绍。

一、@Conditional的源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {

  /**
   * All {@link Condition Conditions} that must {@linkplain Condition#matches match}
   * in order for the component to be registered.
   */
  Class<? extends Condition>[] value();

}

从源码中可以看到,@Conditional注解可以用在类和方法上,需要传入一个实现了Condition接口class数组。

二、代码示例

下面将以不同的操作系统为条件,通过实现Condition接口,并重写其matches方法来构造判断条件。若在Windows系统下运行程序,则输出列表命令为dir;若在Linux系统下运行程序,则输出列表命令为ls。

1.判断条件类的定义

(1).判断Windows的条件

package com.study.day01;

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

/**
 * @Auther: lifq
 * @Description:
 */
public class WindowsCondition implements Condition {
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    return context.getEnvironment().getProperty("os.name").contains("Windows");
  }
}

(2).判断Linux的条件

package com.study.day01;

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

/**
 * @Auther: lifq
 * @Description:
 */
public class LinuxCondition implements Condition {
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    return context.getEnvironment().getProperty("os.name").contains("Linux");
  }
}

2.不同系统下的Bean的类

(1).接口代码

package com.study.day01;

import org.springframework.stereotype.Service;

/**
 * @Auther: lifq
 * @Description:
 */
public interface ListService {

  public String showListCmd();

}

(2).Windows实现类代码

package com.study.day01;

/**
 * @Auther: lifq
 * @Description:
 */
public class WindowsService implements ListService {
  public String showListCmd() {
    return "dir";
  }
}

(3).Linux实现类代码

package com.study.day01;

/**
 * @Auther: lifq
 * @Description:
 */
public class LinuxService implements ListService {
  public String showListCmd() {
    return "ls";
  }
}

3.配置类

package com.study.day01;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;

/**
 * @Auther: lifq
 * @Description:
 */
@Configuration
public class Config {

  @Bean
  @Conditional(WindowsCondition.class)
  public ListService window() {
    return new WindowsService();
  }

  @Bean
  @Conditional(LinuxCondition.class)
  public ListService linux() {
    return new LinuxService();
  }
}

4.运行类

package com.study.day01;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

/**
 * @Auther: lifq
 * @Description:
 */
public class Main01 {

  public static void main (String []args) {

    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);

    ListService listService = applicationContext.getBean(ListService.class);

    System.out.println(applicationContext.getEnvironment().getProperty("os.name") + "系统下的列表命令为:" + listService.showListCmd());
  }
}

我的是Windows操作系统,输出结果为dir,运行截图如下:

运行截图

@Conditional注解例子演示完成,有问题欢迎留言沟通哦!

完整源码地址:https://github.com/suisui2019/springboot-study

三、@Conditional的扩展注解

  • @ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
  • @ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean。
  • @ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean。
  • @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。
  • @ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
  • @ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean。
  • @ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
  • @ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
  • @ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
  • @ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
  • @ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
  • @ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
  • @ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
  • @ConditionalOnExpression:基于SpEL表达式的条件判断。
  • @ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
  • @ConditionalOnResource:当类路径下有指定的资源时触发实例化。
  • @ConditionalOnJndi:在JNDI存在的条件下触发实例化。
  • @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对我们的支持。

(0)

相关推荐

  • Spring Boot 自动配置之条件注解浅析

    Spring Boot 神奇的自动配置,主要依靠大量的条件注解来使用配置自动化. 根据满足某一个特定条件创建一个特定的Bean.比如说,在某些系统变量下创建Bean,或者只有在某个Bean创建后才去创建另外一个Bean. 就是根据条件来控制Bean的创建行为,可以利用该特性来进行一些自动配置. 一.常用的条件注解 @Conditional 依赖的条件 @ConditionalOnBean  在某个Bean存在的条件下 @ConditionalOnMissingBean 在某个Bean不存在的条件

  • Spring的组合注解和元注解原理与用法详解

    本文实例讲述了Spring的组合注解和元注解原理与用法.分享给大家供大家参考,具体如下: 一 点睛 从Spring 2开始,为了相应JDK 1.5推出的注解功能,Spring开始加入注解来替代xml配置.Spring的注解主要用来配置和注入Bean,以及AOP相关配置.随着注解的大量使用,尤其相同的多个注解用到各个类或方法中,会相当繁琐.出现了所谓的样本代码,这是Spring设计要消除的代码. 元注解:可以注解到别的注解上去的注解. 组合注解:被注解的注解,组合注解具备其上的元注解的功能. Sp

  • Spring常用注解汇总

    本文汇总了Spring的常用注解,以方便大家查询和使用,具体如下: 使用注解之前要开启自动扫描功能 其中base-package为需要扫描的包(含子包). <context:component-scan base-package="cn.test"/> @Configuration把一个类作为一个IoC容器,它的某个方法头上如果注册了@Bean,就会作为这个Spring容器中的Bean. @Scope注解 作用域 @Lazy(true) 表示延迟初始化 @Service用于

  • Spring @Bean vs @Service注解区别

    今天跟同事讨论了一下在Spring Boot中,是使用@Configuration和@Bean的组合来创建Bean还是直接使用 @Service等注解放在类上的方式.笔者倾向于使用第一种,即@Configuration和@Bean的组合. 先来看一个例子,目标是创建SearchService的一个Bean. 直接使用@Service的方式: // SearchService.java package li.koly.search; import java.util.List; public in

  • 详解Java的Spring框架中的注解的用法

    1. 使用Spring注解来注入属性 1.1. 使用注解以前我们是怎样注入属性的 类的实现: class UserManagerImpl implements UserManager { private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } ... } 配置文件: <bean id="userManagerImpl" class="com.

  • 详解Spring Data JPA使用@Query注解(Using @Query)

    经过几天的折腾,终于到了学习一个重量级的查询方式上,使用@Query注解,使用注解有两种方式,一种是JPQL的SQL语言方式,一种是原生SQL的语言,略有区别,后者我们更熟悉一些.话不多说,看代码. 1.在CustomerRepository里添加 /** * 模糊匹配 * @param bauer * @return */ @Query("select c from Customer c where c.firstName=?1") Customer findByFirstName2

  • Spring注解@Conditional案例解析

    [1]@Conditional介绍 @Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean. @Conditional源码: //此注解可以标注在类和方法上 @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Conditional { Class<? exten

  • Spring条件注解用法案例分析

    本文实例讲述了Spring条件注解用法.分享给大家供大家参考,具体如下: 一 点睛 Spring 4 提供了一个更通用的基于条件的Bean的创建,即使用@Conditional注解. @Conditional根据满足仅一个特定条件创建一个特定的Bean.也就是根据特定的条件来控制Bean的创建行为,这样就可以利用这个特性进行一些自动的配置. 二 项目说明 以不同的操作系统为条件,通过实现@Condition接口,并重写matches方法来构造条件.若在windows系统下运行,则输出列表命令为d

  • 详解Java Spring各种依赖注入注解的区别

    注解注入顾名思义就是通过注解来实现注入,Spring和注入相关的常见注解有Autowired.Resource.Qualifier.Service.Controller.Repository.Component. Autowired是自动注入,自动从spring的上下文找到合适的bean来注入 Resource用来指定名称注入 Qualifier和Autowired配合使用,指定bean的名称 Service,Controller,Repository分别标记类是Service层类,Contro

  • Spring 4.0新功能:@Conditional注解详细介绍

    前言 最近在学习spring,抽空会将学习的知识总结下面,本文我们会接触spring 4的新功能:@Conditional注解.在之前的spring版本中,你处理conditions只有以下两个方法: 在3.1版本之前,你需要使用spring expression language 在3.1版本发布时,profiles被引入来处理conditions. 让我们分别看看以上两者,在来理解spring 4带来的@Conditional注解. Spring Expression Language(SP

  • Spring的注解配置与XML配置之间的比较

    注释配置相对于 XML 配置具有很多的优势:它可以充分利用 Java 的反射机制获取类结构信息,这些信息可以有效减少配置的工作.如使用 JPA 注释配置 ORM 映射时,我们就不需要指定 PO 的属性名.类型等信息,如果关系表字段和 PO 属性名.类型都一致,您甚至无需编写任务属性映射信息--因为这些信息都可以通过 Java 反射机制获取. 注释和 Java 代码位于一个文件中,而 XML 配置采用独立的配置文件,大多数配置信息在程序开发完成后都不会调整,如果配置信息和 Java 代码放在一起,

  • 浅谈SpringBoot中的@Conditional注解的使用

    概述 Spring boot 中的 @Conditional 注解是一个不太常用到的注解,但确实非常的有用,我们知道 Spring Boot 是根据配置文件中的内容,决定是否创建 bean,以及如何创建 bean 到 Spring 容器中,而 Spring boot 自动化配置的核心控制,就是 @Conditional 注解. @Conditional 注解是 Spring 4.0 之后出的一个注解,与其搭配的一个接口是 Condition,@Conditional 注解会根据具体的条件决定是否

随机推荐