通過@Configuration注解標識的類默認都會被spring加載,但是我們有時候想要通過開關來決定要不要加載,這個時候就需要該博客講解的內容。
我目前了解的兩種實現方式如下
1.自定義@Enable注解
2.通過配置文件配置
自定義@Enable注解
例如:@EnableCaching(緩存)、@EnableScheduling(定時任務),@EnableJpaAuditing(審計),這類注解就像開關一樣,只要在SpringBoot啟動類上加這類注解,就能開啟相關的功能。
本文以日志打印的功能為基礎,實現此功能
1.定義一個LogFilter
public class LogFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("記錄請求日志"); chain.doFilter(request, response); System.out.println("記錄響應日志"); } @Override public void destroy() { } }
2.注冊LogFilter
注意,這里用了@ConditionalOnWebApplication注解,沒有直接使用@Configuration注解。
@ConditionalOnWebApplication public class LogFilterWebConfig { @Bean public LogFilter buildFilter() { return new LogFilter(); } }
3.定義開關@EnableLog注解
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(LogFilterWebConfig.class) public @interface EnableLog { }
4.啟動類上添加注解
@SpringBootApplication @EnableLog public class ConfigSwitchApplication { public static void main(String[] args) { SpringApplication.run(ConfigSwitchApplication.class, args); } }
5.測試
添加一個測試的接口
@RestController public class TestController { @GetMapping("/test") public String test() { System.out.println("test接口被調用"); return "test"; } }
啟動項目,然后訪問http://localhost:8020/test
可以看到控制台已經實現了打印log的功能,我們把@EnableLog注釋掉再啟動測試一下
可以看到日志信息並沒有被打印,代表着LogFilterWebConfig這個類沒有被spring加載。
通過配置文件配置
使用@ConditionalOnProperty注解指定配置項實現
1.修改LogFilterWebConfig類
通過其兩個屬性name以及havingValue來實現的,其中name用來從application.yml中讀取某個屬性值。
如果該值為空,則返回false;
如果值不為空,則將該值與havingValue指定的值進行比較,如果一樣則返回true;否則返回false。
如果返回值為false,則該configuration不生效;為true則生效。
@ConditionalOnProperty(name = "mylog.enable", havingValue = "true") @Configuration public class LogFilterWebConfig { @Bean public LogFilter buildFilter() { return new LogFilter(); } }
2.application.yml文件中添加配置
mylog: enable: true
3.測試
當mylog.enable值為true時候調用接口如下
當mylog.enable值為false時候調用接口如下