@Conditional、@ConditionalOnClass 等条件注解的作用

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)编码思路

       (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下运行控制台打印信息:

Window cmd...

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

Linux cmd...

(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的配置项

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值