@Conditional、ConditionalOnClass和ConditionalOnBean注解

Spring 4框架的新特性:@Conditional注释,此注释使得只有在特定条件满足时才启用一些配置。

本章大纲:

(1)例子说明
(2)编码思路
(3)编写条件类WindowCondition和LinuxCondition
(4)编写接口CmdService以及两个实现类
(5)编写配置类,根据条件进行注入不同的类
(6)编写测试代码
(7)Spring提供的Condition
(8)题外话:怎么在Condition中获取application.properties的配置项

接下里看下具体的内容:

(1)例子说明

在java中这种情况,调用系统的cmd命令,但是我们知道在window和linux下命令有些有些时候是不一样的,那么我们以前一般是这么处理;

//伪代码:  
if(window){  
       //具体的处理代码  
}else if(Linux){  
       //具体的处理代码.  
}  

当具体的处理代码很多的时候,我们会放到另外一个处理类来进行处理,比如:WindowService和LinuxService。你有没有发现这里如果我们使用了@Service进行注解WindowServie和LinuxService的话,那么内存中就会存在两个Service,而实际上有一个service根本一次都不会执行到。好了,针对于这个问题@Conditional就可以解决。当然它还有其它强大的地方。

(2)编码思路

  • 首先这里的话,有一个条件表达式的编写,满足什么条件下返回true,这个是接口Condition,我们需要去实现它;
  • 当满足条件的时候,进行做什么事情,这里使用的是@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. 
 */  
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. 
 */  
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;  
   
/** 
 * 条件配置类. 
 */  
@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下运行控制台打印信息:

 Window cmd...

在Linux下运行控制台打印信息(亲测):

Linux cmd...

(7)Spring提供的Condition

除了自己自定义Condition之外,Spring还提供了很多Condition给我们用

  • @ConditionalOnBean
    仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
  • @ConditionalOnClass
    某个class位于类路径上,才会实例化一个Bean
  • @ConditionalOnExpression
    当表达式为true的时候,才会实例化一个Bean。

比如:

@ConditionalOnExpression("true")
@ConditionalOnExpression("${my.controller.enabled:false}")
  • @ConditionalOnMissingBean
    仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean
  • @ConditionalOnMissingClass
    某个class类路径上不存在的时候,才会实例化一个Bean
  • @ConditionalOnNotWebApplication
    不是web应用

(8)Condition中获取application.properties的配置项

在实际开发中,我们的条件可能保存在application.properties中,那么怎么在Condition中获取呢,这个很简单,主要通过ConditionContext进行获取,具体代码如下:

String port = context.getEnvironment().getProperty("server.port");  
System.out.println(port);  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值