SpringBoot自定义@Configuration配置类启用开关(24)
通过@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时候调用接口如下