We know that spring boot auto-configuration function can decide which spring configuration should be used and which should not be used according to different situations. For example:
- Is Spring's JdbcTemplate in Classpath? If so, and DataSource also exists, automatically configure a JdbcTemplate Bean
- Is Thymeleaf in Classpath? If so, automatically configure Thymeleaf's template parser, view parser, and template engine
How did that come about? The reason is that it takes advantage of Spring's conditional configuration, which allows configurations to exist in applications, but ignores them until certain conditions are met.
To achieve conditional configuration, we need to use @Conditional conditional annotations. Next, write a small example of how @Conditional works.
1. A small example of @Conditional
We know that the command for displaying lists under windows is dir, while the command for displaying lists under linux system is ls. Based on conditional configuration, we can return different values under different operating systems.
- Definition of Judgment Conditions
- Decision Conditions under windows
/** * Implement spring's Condition interface and override the matches() method to return true if the operating system is windows * */ public class WindowsCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Windows"); } }
- The Judgment Conditions under linux
/** * Implement spring's Condition interface and override the matches() method to return true if the operating system is linux * */ public class LinuxCondition implements Condition{ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Linux"); } }
- Decision Conditions under windows
- Classes of Bean s in Different Systems
- Interface
public interface ListService { public String showListLine(); }
- Bean classes under windows
public class WindowsListService implements ListService{ @Override public String showListLine() { return "dir"; } }
- Classes of Bean s under linux
public class LinuxListService implements ListService{ @Override public String showListLine() { return "ls"; } }
- Interface
- Configuration class
@Configuration public class ConditionConfig { /** * Return to the windows ListService instance through the @Conditional annotation when the windows condition is met * */ @Bean @Conditional(WindowsCondition.class) public ListService windonwsListService() { return new WindowsListService(); } /** * Return the linux ListService instance with the @Conditional annotation that meets the linux condition * */ @Bean @Conditional(LinuxCondition.class) public ListService linuxListService() { return new LinuxListService(); } }
- Test class
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") + " The list command under the system is: " + listService.showListLine()); } }
- Running the test class, because I am a Windows 7 system, the result is
The list command under Windows 7 system is: dir
If you're a linux system, the result will be
List commands under Linux system are as follows:ls
2. Conditional configuration of spring boot
There will be a jar package called spring-boot-autoconfigure in the spring boot project
Conditional configuration is implemented in this jar with the following conditional annotations, which start with @Conditional:
Next, let's look at the source code column:
Take Jdbc Template AutoConfiguration for example, which contains this code:
@Bean @Primary @ConditionalOnMissingBean(JdbcOperations.class) public JdbcTemplate jdbcTemplate() { return new JdbcTemplate(this.dataSource); }
A JdbcTemplate Bean is initialized only when there is no instance of JdbcOperations (if you look at the source code of JdbcTemplate, you will find that the JdbcTemplate class implements the JdbcOperations interface).
Based on the above, we can read the source code related to automatic configuration.