【Video & Communication Platform】
http://study.163.com/course/introduction.htm?courseId=1004329008&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
http://study.163.com/course/introduction.htm?courseId=1004638001&utm_campaign=commission&utm_source=400000000155061&utm_medium=share
https://gitee.com/happyangellxq520/spring-boot
à Spring Boot communication platform
http://412887952-qq-com.iteye.com/blog/2321532
New in Spring 4 framework: @Conditional annotation, this annotation enables some configuration to be enabled only when certain conditions are met.
Outline of this chapter:
(2) Coding ideas
(3) Write conditional classes WindowCondition and LinuxCondition
(4) Write interface CmdService and two implementation classes
(5) Write configuration class, inject different classes according to conditions
(6) Write test code
(7) Condition provided by Spring
(8) Digression: How to get the configuration items of application.properties in Condition
Take a look at the specific content below:
( 1 ) Example description
In this case in java , the cmd command of the system is called , but we know that the commands under window and linux are sometimes different, so we usually deal with it like this before;
//Fake code: if(window){ // specific processing code }else if(Linux){ //Specific processing code. }
当具体的处理代码很多的时候,我们会放到另外一个处理类来进行处理,比如:WindowService和LinuxService。你有没有发现这里如果我们使用了@Service进行注解WindowServie和LinuxService的话,那么内存中就会存在两个Service,而实际上有一个service根本一次都不会执行到。好了,针对于这个问题@Conditional就可以解决。当然它还有其它强大的地方。
(2)编码思路
(a)首先这里的话,有一个条件表达式的编写,满足什么条件下返回true,这个是接口Condition,我们需要去实现它;
(b)当满足条件的时候,进行做什么事情,这里使用的是@Conditional,当@Conditional(条件类.class)中的条件类返回true的时候,@Conditional所注解的类或者方法就会执行。
(3)编写条件类WindowCondition和LinuxCondition
WindowCondition:
package com.kfit.demo.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * window操作系统的条件:当在Window系统下运行的时候,matches方法会返回true,否则返回false. * @author Angel --守护天使 * @version v.0.1 * @date 2017年8月23日 */ public class WindowCondition implements Condition{ /** * 这里写自己的逻辑,只有返回true,才会启用配置 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Windows"); } }
window操作系统的条件: 当在Window系统下运行的时候,matches方法会返回true,否则返回false.
LinuxCondition:
package com.kfit.demo.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * Linux操作系统的条件:当在Linux系统下运行的时候,matches方法会返回true,否则返回false. * @author Angel --守护天使 * @version v.0.1 * @date 2017年8月23日 */ public class LinuxCondition implements Condition{ /** * 这里写自己的逻辑,只有返回true,才会启用配置 */ @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { return context.getEnvironment().getProperty("os.name").contains("Linux"); } }
Linux操作系统的条件: 当在Linux系统下运行的时候,matches方法会返回true,否则返回false.
(4)编写接口CmdService以及两个实现类
CmdService
package com.kfit.demo; public interface CmdService { public void print(); }
接口类,具体实现代码有两个service,WindowCmdService和LinuxCmdService。
WindowCmdService:
package com.kfit.demo.service; import com.kfit.demo.CmdService; public class WindowCmdService implements CmdService{ @Override public void print() { System.out.println("Window cmd..."); } }
LinuxCmdService:
package com.kfit.demo.service; import com.kfit.demo.CmdService; public class LinuxCmdService implements CmdService{ @Override public void print() { System.out.println("Linux cmd..."); } }
注意:以上的两个实现类WindowCmdService和LinuxCmdService这里我们并没有使用@Service注解进行注入,下面我们使用配置类根据不同的系统注入不同的类。
(5)编写配置类,根据条件进行注入不同的类
CmdServiceConditionConfig:
package com.kfit.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import com.kfit.demo.CmdService; import com.kfit.demo.condition.LinuxCondition; import com.kfit.demo.condition.WindowCondition; import com.kfit.demo.service.LinuxCmdService; import com.kfit.demo.service.WindowCmdService; /** * 条件配置类. * @author Angel --守护天使 * @version v.0.1 * @date 2017年8月23日 */ @Configuration public class CmdServiceConditionConfig { /** * 当WindowCondition方法中的matches返回true的时候, * WindowCmdService会被注入,否则不注入。 */ @Bean("cmdService") @Conditional(WindowCondition.class) public CmdService windowCmdService(){ return new WindowCmdService(); } /** * 当LinuxCondition方法中的matches返回true的时候, * LinuxCmdService会被注入,否则不注入。 */ @Bean("cmdService") @Conditional(LinuxCondition.class) public CmdService LinuxCmdService(){ return new LinuxCmdService(); } }
这里使用@Conditional根据满足不同的条件注入不同的类,在Linux下会注入实现类LinuxCmdService,在Window下会注入WindowCmdService。
(6)编写测试代码
在启动类的main方法中编写测试代码:
public static void main(String[] args) { ApplicationContext ctx = (ApplicationContext) SpringApplication.run(App.class, args); CmdService cmdService = ctx.getBean(CmdService.class); cmdService.print(); }
在Window下运行控制台打印信息:
在Linux下运行控制台打印信息(亲测):
(7)Spring提供的Condition
除了自己自定义Condition之外,Spring还提供了很多Condition给我们用
(a)@ConditionalOnBean
仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
(b)@ConditionalOnClass
某个class位于类路径上,才会实例化一个Bean
(c)@ConditionalOnExpression
当表达式为true的时候,才会实例化一个Bean。
比如:
@ConditionalOnExpression("true")
@ConditionalOnExpression("${my.controller.enabled:false}")
(d)@ConditionalOnMissingBean
仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean
(e)@ConditionalOnMissingClass
某个class类路径上不存在的时候,才会实例化一个Bean
(f)@ConditionalOnNotWebApplication
不是web应用
(8)题外话:怎么在Condition中获取application.properties的配置项
在实际开发中,我们的条件可能保存在application.properties中,那么怎么在Condition中获取呢,这个很简单,主要通过ConditionContext进行获取,具体代码如下:
String port = context.getEnvironment().getProperty("server.port"); System.out.println(port);
视频&交流平台:
http://study.163.com/course/introduction.htm?courseId=1004329008
http://412887952-qq-com.iteye.com/blog/2321532