This article brings you an introduction to conditional judgment in Spring Boot (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Those Conditionals in Spring Boot
spring boot provides us with a rich set of Conditionals that allow us to add beans to the container in the project very conveniently. This article mainly explains each annotation and illustrates its use with code.
All ConditionalOnXXX annotations can be placed on class or method. If the method is on class, it will determine whether all @Bean annotated methods in the class are executed.
@Conditional
The other Conditional annotations below are all syntactic sugar. You can customize ConditionalOnXXX through the following method.
The Conditional annotation is defined as follows and receives the class array that implements the Condition interface.
public @interface Conditional {
Class extends Condition>[] value();
}
The Condition interface has only one matches method, which returns the result of matching.
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
Configure conditions through the operating system to configure Bean. When Window is used, Bill's Person object is instantiated, and when Linux is used, Linus' Person object is instantiated.
//LinuxCondition,为方便起见,去掉判断代码,直接返回true了
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return true;
}
}
//WindowsCondition,为方便起见,去掉判断代码,直接返回false了
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
return false;
}
}
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private Integer age;
}
//配置类
@Configuration
public class BeanConfig {
@Bean(name = "bill")
@Conditional({WindowsCondition.class})
public Person person1(){
return new Person("Bill Gates",62);
}
@Bean("linus")
@Conditional({LinuxCondition.class})
public Person person2(){
return new Person("Linus",48);
}
}
public class AppTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test(){
String osName = applicationContext.getEnvironment().getProperty("os.name");
System.out.println("当前系统为:" + osName);
Map<string> map = applicationContext.getBeansOfType(Person.class);
System.out.println(map);
}
}</string>
Output results:
The current system is: Mac OS X
{linus=Person(name=Linus, age=48)}
@ConditionalOnBean & @ ConditionalOnMissingBean
These two annotations will judge the Bean object in the Bean container. The example used is during configuration. If it is found that there is no Computer instance, a backup computer will be instantiated.
@Data
@AllArgsConstructor
@ToString
public class Computer {
private String name;
}
@Configuration
public class BeanConfig {
@Bean(name = "notebookPC")
public Computer computer1(){
return new Computer("笔记本电脑");
}
@ConditionalOnMissingBean(Computer.class)
@Bean("reservePC")
public Computer computer2(){
return new Computer("备用电脑");
}
}
public class TestApp {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test1(){
Map<string> map = applicationContext.getBeansOfType(Computer.class);
System.out.println(map);
}
}</string>
Modify BeanConfig, if you comment out the first @Bean, the backup computer will be instantiated, otherwise the backup computer will not be instantiated
@ConditionalOnClass & @ConditionalOnMissingClass
This annotation will determine whether there is a specified class on the class path. It was confusing when I first saw it. If there is no specified class on the class path, the compilation will not pass... This is mainly used to integrate third parties with the same functions. When using a component, as long as there is a class of the component on the class path, it will be automatically configured. For example, when spring boot web automatically configures the view component, it uses Velocity, Thymeleaf, or freemaker. This is the method used.
The example is two sets of armor A (light suit) and B (dark suit). If A is not present, configure B.
public interface Fighter {
void fight();
}
public class FighterA implements Fighter {
@Override
public void fight() {
System.out.println("使用光明套装");
}
}
public class FighterB implements Fighter {
@Override
public void fight() {
System.out.println("使用暗黑套装");
}
}
Van is a samurai and uses the suit to fight
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Van {
private Fighter fighter;
public void fight(){
fighter.fight();
}
}
VanConfigA/B instantiates the samurai
@Configuration
@ConditionalOnClass({FighterA.class})
public class VanConfigA {
@Primary
@Bean
public Van vanA(){
return new Van(new FighterA());
}
}
@Configuration
@ConditionalOnClass({FighterB.class})
public class VanConfigB {
@Bean
public Van vanB(){
return new Van(new FighterB());
}
}
Test class, by default, if suit AB is on the class path, Both sets will be loaded, and A will be set to PRIMARY. If FightA.class is deleted in the target class, only set B will be loaded.
@SpringBootApplication
public class TestApp implements CommandLineRunner {
@Autowired
private Van van;
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
@Override
public void run(String... args) throws Exception {
//do something
van.fight();
}
}
In addition, try to merge the two VanConfigA/B and put the annotation ConditionalOnClass on the method. If you delete a suit, an error will occur.
@ConditionalOnExpress
Perform conditional judgment based on expressions. This function can be used in most cases with @ConditionalOnProperty. The expression is more flexible because SpEL can be used. In the example, the value of test.enabled in properties will be judged. BeanConfig judges three types of Boolean, string and number respectively. I have tried many other methods but none of them work, such as using == directly. It seems that the configured attributes will be treated as strings.
@Data
public class TestBean {
private String name;
}
@Configuration
@ConditionalOnExpression("#{${test.enabled:true} }")
//@ConditionalOnExpression("'zz'.equalsIgnoreCase('${test.name2}')")
//@ConditionalOnExpression("new Integer('${test.account}')==1")
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean("我是美猴王");
}
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
@Autowired
private TestBean testBean;
public static void main(String[] args) {
SpringApplication.run(TestAppCommand.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(testBean.getName());
}
}
@ConditionalOnProperty
is suitable for conditional judgment on a single Property, while the @ConditionalOnExpress above is suitable for more complex situations, such as the associated comparison of multiple properties. This example also gives three basic types of conditional judgments, but it seems that they can all be treated as strings...
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestBean {
private String name;
}
@Configuration
@ConditionalOnProperty(prefix = "test", name="enabled", havingValue = "true",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="account", havingValue = "1",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="name1", havingValue = "zz",matchIfMissing = false)
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean("我是美猴王");
}
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
@Autowired
private TestBean testBean;
public static void main(String[] args) {
SpringApplication.run(TestAppCommand.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(testBean.getName());
}
}
@ConditionalOnJava
Can be judged by the java version.
@Data
public class TestBean {
}
@Configuration
@ConditionalOnJava(JavaVersion.EIGHT)
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean();
}
}
public class TestApp {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test(){
Map<string> map = context.getBeansOfType(TestBean.class);
System.out.println(map);
}
}</string>
@ConditionalOnResource
Conditional judgment is made based on whether the specified resource file exists, such as judging ehcache.properties to determine whether to automatically assemble the ehcache component.
@Data
public class TestBean {
}
@Configuration
@ConditionalOnResource(resources = "classpath:application.yml")
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean();
}
}
public class TestApp {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test(){
Map<string> map = context.getBeansOfType(TestBean.class);
System.out.println(map);
}
}</string>
@ConditionalOnSingleCandidate
I haven’t thought of the application scenario yet. The conditions for passing the condition are: 1. There is only one corresponding bean container. 2. There are multiple corresponding beans, but PRIMARY has been formulated. . In the example, when assembling BeanB, you need to check the assembly status of BeanA, so BeanBConfig should be ranked after BeanAConfig. You can modify BeanAConfig and remove the @Primary annotation, or remove the three @Bean annotations, and BeanB will not be instantiated.
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BeanA {
private String name;
}
@Configuration
public class BeanAConfig {
@Bean
@Primary
public BeanA bean1(){
return new BeanA("bean1");
}
@Bean(autowireCandidate = false)
public BeanA bean2(){
return new BeanA("bean2");
}
//@Bean(autowireCandidate = false)
public BeanA bean3(){
return new BeanA("bean3");
}
}
@Data
public class BeanB {
}
@Configuration
@AutoConfigureAfter(BeanAConfig.class)
@ConditionalOnSingleCandidate(BeanA.class)
public class BeanBConfig {
@Bean
public BeanB targetBean(){
return new BeanB();
}
}
public class TestApp {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanAConfig.class, BeanBConfig.class);
@Test
public void test(){
Map<string> map = context.getBeansOfType(BeanA.class);
System.out.println(map);
Map<string> map2 = context.getBeansOfType(BeanB.class);
System.out.println(map2);
}
}</string></string>
@ConditionalOnNotWebApplication & @ConditionalOnWebApplication
Determine whether the current environment is a Web application.
//LinuxCondition,为方便起见,去掉判断代码,直接返回true了
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return true;
}
}
//WindowsCondition,为方便起见,去掉判断代码,直接返回false了
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata metadata) {
return false;
}
}
@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private String name;
private Integer age;
}
//配置类
@Configuration
public class BeanConfig {
@Bean(name = "bill")
@Conditional({WindowsCondition.class})
public Person person1(){
return new Person("Bill Gates",62);
}
@Bean("linus")
@Conditional({LinuxCondition.class})
public Person person2(){
return new Person("Linus",48);
}
}
public class AppTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test(){
String osName = applicationContext.getEnvironment().getProperty("os.name");
System.out.println("当前系统为:" + osName);
Map<string> map = applicationContext.getBeansOfType(Person.class);
System.out.println(map);
}
}</string>Output results: The current system is: Mac OS X{linus=Person(name=Linus, age=48)}
@ConditionalOnBean & @ ConditionalOnMissingBean
@Data
@AllArgsConstructor
@ToString
public class Computer {
private String name;
}
@Configuration
public class BeanConfig {
@Bean(name = "notebookPC")
public Computer computer1(){
return new Computer("笔记本电脑");
}
@ConditionalOnMissingBean(Computer.class)
@Bean("reservePC")
public Computer computer2(){
return new Computer("备用电脑");
}
}
public class TestApp {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test1(){
Map<string> map = applicationContext.getBeansOfType(Computer.class);
System.out.println(map);
}
}</string>Modify BeanConfig, if you comment out the first @Bean, the backup computer will be instantiated, otherwise the backup computer will not be instantiated @ConditionalOnClass & @ConditionalOnMissingClass This annotation will determine whether there is a specified class on the class path. It was confusing when I first saw it. If there is no specified class on the class path, the compilation will not pass... This is mainly used to integrate third parties with the same functions. When using a component, as long as there is a class of the component on the class path, it will be automatically configured. For example, when spring boot web automatically configures the view component, it uses Velocity, Thymeleaf, or freemaker. This is the method used. The example is two sets of armor A (light suit) and B (dark suit). If A is not present, configure B.Van is a samurai and uses the suit to fightpublic interface Fighter { void fight(); } public class FighterA implements Fighter { @Override public void fight() { System.out.println("使用光明套装"); } } public class FighterB implements Fighter { @Override public void fight() { System.out.println("使用暗黑套装"); } }
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Van {
private Fighter fighter;
public void fight(){
fighter.fight();
}
}
VanConfigA/B instantiates the samurai
@Configuration
@ConditionalOnClass({FighterA.class})
public class VanConfigA {
@Primary
@Bean
public Van vanA(){
return new Van(new FighterA());
}
}
@Configuration
@ConditionalOnClass({FighterB.class})
public class VanConfigB {
@Bean
public Van vanB(){
return new Van(new FighterB());
}
}Test class, by default, if suit AB is on the class path, Both sets will be loaded, and A will be set to PRIMARY. If FightA.class is deleted in the target class, only set B will be loaded.
@SpringBootApplication
public class TestApp implements CommandLineRunner {
@Autowired
private Van van;
public static void main(String[] args) {
SpringApplication.run(TestApp.class, args);
}
@Override
public void run(String... args) throws Exception {
//do something
van.fight();
}
}In addition, try to merge the two VanConfigA/B and put the annotation ConditionalOnClass on the method. If you delete a suit, an error will occur. @ConditionalOnExpress
Perform conditional judgment based on expressions. This function can be used in most cases with @ConditionalOnProperty. The expression is more flexible because SpEL can be used. In the example, the value of test.enabled in properties will be judged. BeanConfig judges three types of Boolean, string and number respectively. I have tried many other methods but none of them work, such as using == directly. It seems that the configured attributes will be treated as strings.
@Data
public class TestBean {
private String name;
}
@Configuration
@ConditionalOnExpression("#{${test.enabled:true} }")
//@ConditionalOnExpression("'zz'.equalsIgnoreCase('${test.name2}')")
//@ConditionalOnExpression("new Integer('${test.account}')==1")
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean("我是美猴王");
}
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
@Autowired
private TestBean testBean;
public static void main(String[] args) {
SpringApplication.run(TestAppCommand.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(testBean.getName());
}
}
@ConditionalOnProperty
is suitable for conditional judgment on a single Property, while the @ConditionalOnExpress above is suitable for more complex situations, such as the associated comparison of multiple properties. This example also gives three basic types of conditional judgments, but it seems that they can all be treated as strings...
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestBean {
private String name;
}
@Configuration
@ConditionalOnProperty(prefix = "test", name="enabled", havingValue = "true",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="account", havingValue = "1",matchIfMissing = false)
//@ConditionalOnProperty(prefix = "test", name="name1", havingValue = "zz",matchIfMissing = false)
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean("我是美猴王");
}
}
@SpringBootApplication
public class TestAppCommand implements CommandLineRunner {
@Autowired
private TestBean testBean;
public static void main(String[] args) {
SpringApplication.run(TestAppCommand.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(testBean.getName());
}
}
@ConditionalOnJava
Can be judged by the java version.
@Data
public class TestBean {
}
@Configuration
@ConditionalOnJava(JavaVersion.EIGHT)
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean();
}
}
public class TestApp {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test(){
Map<string> map = context.getBeansOfType(TestBean.class);
System.out.println(map);
}
}</string>
@ConditionalOnResource
Conditional judgment is made based on whether the specified resource file exists, such as judging ehcache.properties to determine whether to automatically assemble the ehcache component.
@Data
public class TestBean {
}
@Configuration
@ConditionalOnResource(resources = "classpath:application.yml")
public class BeanConfig {
@Bean
public TestBean testBean(){
return new TestBean();
}
}
public class TestApp {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanConfig.class);
@Test
public void test(){
Map<string> map = context.getBeansOfType(TestBean.class);
System.out.println(map);
}
}</string>
@ConditionalOnSingleCandidate
这个还没有想到应用场景,条件通过的条件是:1 对应的bean容器中只有一个 2.对应的bean有多个,但是已经制定了PRIMARY。例子中,BeanB装配的时候需要看BeanA的装配情况,所以BeanBConfig要排在BeanAConfig之后.可以修改BeanAConfig,将@Primary注解去掉,或者把三个@Bean注解去掉,BeanB就不会实例化了。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BeanA {
private String name;
}
@Configuration
public class BeanAConfig {
@Bean
@Primary
public BeanA bean1(){
return new BeanA("bean1");
}
@Bean(autowireCandidate = false)
public BeanA bean2(){
return new BeanA("bean2");
}
//@Bean(autowireCandidate = false)
public BeanA bean3(){
return new BeanA("bean3");
}
}
@Data
public class BeanB {
}
@Configuration
@AutoConfigureAfter(BeanAConfig.class)
@ConditionalOnSingleCandidate(BeanA.class)
public class BeanBConfig {
@Bean
public BeanB targetBean(){
return new BeanB();
}
}
public class TestApp {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanAConfig.class, BeanBConfig.class);
@Test
public void test(){
Map<string> map = context.getBeansOfType(BeanA.class);
System.out.println(map);
Map<string> map2 = context.getBeansOfType(BeanB.class);
System.out.println(map2);
}
}</string></string>
@ConditionalOnNotWebApplication & @ConditionalOnWebApplication
判断当前环境是否是Web应用。
你可能感兴趣的
评论
![]()
The above is the detailed content of Introduction to conditional judgment in Spring Boot (with code). For more information, please follow other related articles on the PHP Chinese website!
How do I use Maven or Gradle for advanced Java project management, build automation, and dependency resolution?Mar 17, 2025 pm 05:46 PMThe article discusses using Maven and Gradle for Java project management, build automation, and dependency resolution, comparing their approaches and optimization strategies.
How do I create and use custom Java libraries (JAR files) with proper versioning and dependency management?Mar 17, 2025 pm 05:45 PMThe article discusses creating and using custom Java libraries (JAR files) with proper versioning and dependency management, using tools like Maven and Gradle.
How do I implement multi-level caching in Java applications using libraries like Caffeine or Guava Cache?Mar 17, 2025 pm 05:44 PMThe article discusses implementing multi-level caching in Java using Caffeine and Guava Cache to enhance application performance. It covers setup, integration, and performance benefits, along with configuration and eviction policy management best pra
How can I use JPA (Java Persistence API) for object-relational mapping with advanced features like caching and lazy loading?Mar 17, 2025 pm 05:43 PMThe article discusses using JPA for object-relational mapping with advanced features like caching and lazy loading. It covers setup, entity mapping, and best practices for optimizing performance while highlighting potential pitfalls.[159 characters]
How does Java's classloading mechanism work, including different classloaders and their delegation models?Mar 17, 2025 pm 05:35 PMJava's classloading involves loading, linking, and initializing classes using a hierarchical system with Bootstrap, Extension, and Application classloaders. The parent delegation model ensures core classes are loaded first, affecting custom class loa


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

PhpStorm Mac version
The latest (2018.2.1) professional PHP integrated development tool

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

VSCode Windows 64-bit Download
A free and powerful IDE editor launched by Microsoft





##
Java 

