• Spring @Conditional


    Class Conditions

    Include a configuration bean only if a specified class is present using the @ConditionalOnClass annotation
    Include a configuration bean only if a specified class is absent using the @ConditionalOnMissingClass annotation.

    @Configuration
    @ConditionalOnClass(DataSource.class)
    public class MySQLAutoconfiguration {
        //...
    }
    
    @Configuration
    @ConditionalOnMissingClass(DataSource.class)
    public class MySQLAutoconfiguration {
        //...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Bean Conditions

    Include a bean only if a specified bean is present use the @ConditionalOnBean annotations.
    Include a bean only if a specified bean is absent use the @ConditionalOnMissingBean annotations.

    @Bean
    @ConditionalOnBean(name = "dataSource")
    @ConditionalOnMissingBean
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
        em.setDataSource(dataSource());
        em.setPackagesToScan("com.autoconfiguration.example");
        em.setJpaVendorAdapter(new HibernateJpaVendorAdapter());
        if (additionalProperties() != null) {
            em.setJpaProperties(additionalProperties());
        }
        return em;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    @Bean
    @ConditionalOnMissingBean(type = "JpaTransactionManager")
    public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    Property Conditions

    Use the @ConditionalOnProperty annotation to specify if a configuration loads based on the presence and value of a Spring Environment property.

    # 文件 mysql.properties
    usemysql=local
    
    • 1
    • 2
    @Bean
    @ConditionalOnProperty(name = "usemysql", havingValue = "local")
    @ConditionalOnMissingBean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/myDb?createDatabaseIfNotExist=true");
        dataSource.setUsername("mysqluser");
        dataSource.setPassword("mysqlpass");
        return dataSource;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    # configure the dataSource bean using custom properties values
    
    @Bean(name = "dataSource")
    @ConditionalOnProperty(name = "usemysql", havingValue = "custom")
    @ConditionalOnMissingBean
    public DataSource dataSource2() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl(env.getProperty("mysql.url"));
        dataSource.setUsername(env.getProperty("mysql.user") != null ? env.getProperty("mysql.user") : "");
        dataSource.setPassword(env.getProperty("mysql.pass") != null ? env.getProperty("mysql.pass") : "");
        return dataSource;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Resource Conditions

    The configuration loads only when a specified resource is present use the @ConditionalOnResource annotation.

    # 文件 mysql.properties
    mysql-hibernate.dialect=org.hibernate.dialect.MySQLDialect
    mysql-hibernate.show_sql=true
    mysql-hibernate.hbm2ddl.auto=create-drop
    
    • 1
    • 2
    • 3
    • 4
    @ConditionalOnResource(resources = "classpath:mysql.properties")
    public Properties additionalProperties() {
        Properties hibernateProperties = new Properties();
        
        hibernateProperties.setProperty("hibernate.hbm2ddl.auto", env.getProperty("mysql-hibernate.hbm2ddl.auto"));
        hibernateProperties.setProperty("hibernate.dialect", env.getProperty("mysql-hibernate.dialect"));
        hibernateProperties.setProperty("hibernate.show_sql", env.getProperty("mysql-hibernate.show_sql") != null ? env.getProperty("mysql-hibernate.show_sql") : "false");
        return hibernateProperties;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Expression Conditional

    Use @ConditionalExpression annotation in more complex situations. Spring will use the marked definition when the SpEL expression is evaluated to true:

    @Bean
    @ConditionalOnExpression("${usemysql} && ${mysqlserver == 'local'}")
    DataSource dataSource() {
        // ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Custom Conditions

    Use @Conditional to define custom conditions by extending the SpringBootCondition class and overriding the getMatchOutcome() method.

    public class HibernateCondition extends SpringBootCondition {
    
        private static String[] CLASS_NAMES = {"org.hibernate.ejb.HibernateEntityManager", "org.hibernate.jpa.HibernateEntityManager"};
    
        @Override
        public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
    
            ConditionMessage.Builder message = ConditionMessage.forCondition("Hibernate");
    
            return Arrays.stream(CLASS_NAMES)
                    .filter(className -> ClassUtils.isPresent(className, context.getClassLoader()))
                    .map(className -> ConditionOutcome.match(message.found("class").items(ConditionMessage.Style.NORMAL, className)))
                    .findAny()
                    .orElseGet(() -> ConditionOutcome.noMatch(message.didNotFind("class", "classes").items(ConditionMessage.Style.NORMAL, Arrays.asList(CLASS_NAMES))));
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    @Conditional(HibernateCondition.class)
    Properties additionalProperties() {
      //...
    }
    
    • 1
    • 2
    • 3
    • 4

    Application Conditions

    We can also specify that the configuration can load only inside/outside a web context. In order to do this, we can add the @ConditionalOnWebApplication or @ConditionalOnNotWebApplication annotation.

    @ConditionalOnWebApplication
    HealthCheckController healthCheckController() {
        // ...
    }
    
    • 1
    • 2
    • 3
    • 4

    Disabling Auto-Configuration Classes

    Use the @EnableAutoConfiguration annotation with exclude or excludeName attribute to a configuration class to exclude the auto-configuration from loading.

    @Configuration
    @EnableAutoConfiguration(exclude={MySQLAutoconfiguration.class})
    public class AutoconfigurationApplication {
        //...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    We can also set the spring.autoconfigure.exclude property

    spring.autoconfigure.exclude=com.baeldung.autoconfiguration.MySQLAutoconfiguration
    
    • 1

    参考: Create a Custom Auto-Configuration with Spring Boot

  • 相关阅读:
    Shire.run:Prompt 即代码到 Prompt 即程序,思考 Prompt 的无限可能性
    智慧交通行业发展现状及竞争格局发展前景分析
    算法ppt练习题(给黄成个大逼兜)
    解锁网络世界的利器:代理IP与Socks5代理
    bigemap在林业勘测规划设计行业的一些应用
    刨根问底 Redis, 面试过程真好使
    【Qt 学习笔记】Qt常用控件 | 显示类控件 | Label的使用及说明
    基于go语言的史上最流弊的学生成绩管理系统
    MySQL进阶实战9,InnoDB和MyISAM的数据分布对比
    中国石油大学《高等数学二》第三次在线作业
  • 原文地址:https://blog.csdn.net/weixin_37646636/article/details/133699410