0
点赞
收藏
分享

微信扫一扫

Spring 条件注解之@Conditional


@Conditional 是 Spring4 新增的注解,其内部主要就是利用了 Condition 接口来判断是否满足条件,从而决定是否需要加载Bean并注入到Spring容器中。

 

定义操作系统的具体行为

操作系统接口

public interface OsEnvironment {
/**
* 更改目录
*
* @return .
* */
String directoryListing();

/**
* 清空屏幕
*
* @return .
*/
String clearScreen();


/**
* 文件复制
*
* @return .
*/
String fileCopy();
}

Windows 环境

public class WindowsEnvironment implements OsEnvironment {
@Override
public String directoryListing() {
return "dir";
}

@Override
public String clearScreen() {
return "cls";
}

@Override
public String fileCopy() {
return "copy";
}
}

Linux 环境

public class LinuxEnvironment implements OsEnvironment {
@Override
public String directoryListing() {
return "ls";
}

@Override
public String clearScreen() {
return "clear";
}

@Override
public String fileCopy() {
return "cp";
}
}

 

定义操作系统环境条件

Windows 环境条件类

public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String osName = conditionContext.getEnvironment().getProperty("os.name");
return !StringUtils.isEmpty(osName) && osName.contains("Windows");
}
}

Linux 环境条件类

public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String osName = conditionContext.getEnvironment().getProperty("os.name");
return !StringUtils.isEmpty(osName) && osName.contains("Linux");
}
}

 

配置类

根据配置来选择具体实例化哪个操作系统环境信息

@Configuration
@Slf4j
public class ConditionConfiguration {

/**
* 如果满足 LinuxCondition(即: matches 返回 true), 则实例化 LinuxEnvironment
* */
@Bean
@Conditional(LinuxCondition.class)
public OsEnvironment linuxListService() {
log.info("当前服务运行在 Linux 环境");
return new LinuxEnvironment();
}

/**
* 如果满足 WindowsCondition(即: matches 返回 true), 则实例化 WindowsEnvironment
* */
@Bean
@Conditional(WindowsCondition.class)
public OsEnvironment windowsListService() {
log.info("当前服务运行在 Windows 环境");
return new WindowsEnvironment();
}
}

 

验证

@Slf4j
@Component
public class ServiceInitialize implements InitializingBean {

@Autowired
private OsEnvironment osEnvironment;

@Autowired
private ApplicationContext applicationContext;

@Override
public void afterPropertiesSet() throws Exception {
log.info("InitializingBean init...");

log.info("directoryListing={}", osEnvironment.directoryListing());
log.info("clearScreen={}", osEnvironment.clearScreen());
log.info("fileCopy={}", osEnvironment.fileCopy());


System.out.println("\n\n");
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
log.info(beanDefinitionName);
}
System.out.println("\n\n");

log.info("InitializingBean init end...");
}
}

 

@ConditionalOnExpression 使用

如果 觉得每个条件都要编写实现类 ​​public class XXX implements Condition​​​ 有点繁琐, 可以使用 ​​@ConditionalOnExpression​​ 注解

@Configuration
@Slf4j
public class ConditionConfiguration {

/**
* 如果满足 LinuxCondition(即: matches 返回 true), 则实例化 LinuxEnvironment
* */
@Bean
// @Conditional(LinuxCondition.class)
@ConditionalOnExpression("#{systemProperties['os.name'].contains('Linux')}")
public OsEnvironment linuxListService() {
log.info("当前服务运行在 Linux 环境");
return new LinuxEnvironment();
}

/**
* 如果满足 WindowsCondition(即: matches 返回 true), 则实例化 WindowsEnvironment
* */
@Bean
// @Conditional(WindowsCondition.class)
@ConditionalOnExpression("#{systemProperties['os.name'].contains('Windows')}")
public OsEnvironment windowsListService() {
log.info("当前服务运行在 Windows 环境");
return new WindowsEnvironment();
}
}

 

Spring框架提供了一系列相关的注解

注解

说明

​@ConditionalOnSingleCandidate​

当给定类型的bean存在并且指定为Primary的给定类型存在时,返回true

​@ConditionalOnMissingBean​

当给定的类型、类名、注解、昵称在beanFactory中不存在时返回true.各类型间是or的关系

​@ConditionalOnBean​

与上面相反,要求bean存在

​@ConditionalOnMissingClass​

当给定的类名在类路径上不存在时返回true,各类型间是and的关系

​@ConditionalOnClass​

与上面相反,要求类存在

​@ConditionalOnCloudPlatform​

当所配置的CloudPlatform为激活时返回true

​@ConditionalOnExpression​

spel表达式执行为true

​@ConditionalOnJava​

运行时的java版本号是否包含给定的版本号.如果包含,返回匹配,否则,返回不匹配

​@ConditionalOnProperty​

要求配置属性匹配条件

​@ConditionalOnJndi​

给定的jndi的Location 必须存在一个.否则,返回不匹配

​@ConditionalOnNotWebApplication​

web环境不存在时

​@ConditionalOnWebApplication​

web环境存在时

​@ConditionalOnResource​

要求制定的资源存在

// 如果配置属性中显示的声明 study.enable=true ,则当前的整体系才生效
@ConditionalOnProperty(prefix ="study", name="enable", havingValue="true")

// 如果没有显示设置study.enable的值时也会正常加载
@ConditionalOnProperty(prefix ="study", name="enable", havingValue="true", matchIfMissing = true)

  • havingValue: 比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置
  • matchIfMissing: 缺少该property时是否可以加载。如果为true,没有该property也会正常加载;反之报错

 

// MybatisAutoConfiguration会在DataSourceAutoConfiguration之后加载
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration implements InitializingBean {
}


举报

相关推荐

0 条评论