Sprboot Series 6: @Conditional and Sprboot Autoconfiguration

Keywords: Java Spring Windows Linux Thymeleaf

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.

  1. Definition of Judgment Conditions
    1. 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");
          }
      
          
      }
    2. 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");
          }
      
          
      }
  2. Classes of Bean s in Different Systems
    1. Interface
      public interface ListService {
      
          public String showListLine();
      }
    2. Bean classes under windows
      public class WindowsListService implements ListService{
      
          @Override
          public String showListLine() {
              return "dir";
          }
      
      }
    3. Classes of Bean s under linux
      public class LinuxListService implements ListService{
      
          @Override
          public String showListLine() {
              return "ls";
          }
      
      }
  3. 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();
        }
    }
  4. 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());
        }
    }
  5. 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.

Posted by fadedline on Thu, 13 Dec 2018 23:30:06 -0800