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)