通過@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時候調用接口如下

