1. 簡介
Spring Boot通過@ConditionalOnProperty來控制Configuration是否生效
2. 說明
@Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.TYPE, ElementType.METHOD }) @Documented @Conditional(OnPropertyCondition.class) public @interface ConditionalOnProperty { String[] value() default {}; //數組,獲取對應property名稱的值,與name不可同時使用 String prefix() default "";//property名稱的前綴,可有可無 String[] name() default {};//數組,property完整名稱或部分名稱(可與prefix組合使用,組成完整的property名稱),與value不可同時使用 String havingValue() default "";//可與name組合使用,比較獲取到的屬性值與havingValue給定的值是否相同,相同才加載配置 boolean matchIfMissing() default false;//缺少該property時是否可以加載。如果為true,沒有該property也會正常加載;反之報錯 boolean relaxedNames() default true;//是否可以松散匹配 }
3. 使用方法
通過其兩個屬性name以及havingValue來實現的,其中name用來從application.properties中讀取某個屬性值。
如果該值為空,則返回false;
如果值不為空,則將該值與havingValue指定的值進行比較,如果一樣則返回true;否則返回false。
如果返回值為false,則該configuration不生效;為true則生效。
4.使用示例
我們來模擬通過application.yml配置文件來配置我們的服務是使用Nosql型的數據庫還是sql數據庫
application.yml的配置如下:
database:
type: "${DATABASE_TYPE:cassandra}" # cassandra OR sql
這里我們分別定義Nosql的注解與sql的注解
@ConditionalOnProperty(prefix = "database", value = "type", havingValue = "cassandra") public @interface NoSqlDao { } @ConditionalOnProperty(prefix = "database", value = "type", havingValue = "sql") public @interface SqlDao { }
然后簡單的寫一下dao的實現:
public interface DeviceDao { List<Device> findDevicesByCustomerId(UUID customerId); } @Component @SqlDao public class JpaDeviceDao implements DeviceDao { @Override public List<Device> findDevicesByCustomerId(UUID customerId) { return null; } } @Component @NoSqlDao public class CassandraDeviceDao implements DeviceDao { @Override public List<Device> findDevicesByCustomerId(UUID customerId) { return null; } }
那么當我們想使用cassandra數據庫的時候,只需要更改yml配置文件為cassandra。
而在DeviceServiceImpl中,代碼則不需要進行更改,因為此時@ConditionalOnProperty注解讓我們的JpaDeviceDao的注入失效了,所以會自動匹配CassandraDao
@Autowired private DeviceDao deviceDao;
