Spring的profile与条件注入浅谈【原创】

Spring环境与profile、条件化的bean(@condition)浅谈

作者的话

对于不同的环境,代码是有些差异的,开发环境、验证环境或者是生成环境,这就是需要用到profile来限定不同环境选择初始化的bean是不同的,或者是满足了某些条件才会去初始化特别的bean。

本篇文章主要谈及到两个知识点,spring的profile和注解condition,也引入一下简单的代码来验证。

对于项目来说,一般开发是直接在开发环境dev进行,如果没有问题会在SIT(System Integration Testing)系统集成测试,再到UAT(User Acceptance Testing)用户验收测试,最终上生产,这些都是需要不同的数据库或者是流程平台等,不可能换个环境就手动改很多代码。

代码示例

1、profile的使用

需要测试的bean,用于注入的spring

public class DemoBean {
​
 private String content;
​
 public DemoBean(String content) {
 super();
 this.content = content;
 }
​
 public String getContent() {
 return content;
 }
​
 public void setContent(String content) {
 this.content = content;
 }
}

配置类,对于Bean可以是数据库信息等的声明

@Configuration
public class ProfileConfig {
​
 /**
 * Profile 为dev时,实例化devDemoBean 开发环境
 * @return
 */
 @Bean
 @Profile("dev")
 public DemoBean devDemoBean() {
 return new DemoBean("from development profile");
 }
​
 /**
 * Profile 为prod时,实例化prodDemoBean  生成环境
 * @return
 */
 @Bean
 @Profile("prod")
 public DemoBean prodDemoBean() {
 return new DemoBean("from production profile");
 }
}

测试程序入口

public class ProfileMain {
 public static void main(String[] args) {
 AnnotationConfigApplicationContext context =
 new AnnotationConfigApplicationContext(ProfileConfig.class);
​
 /**
 * 1、先将活动的profile设置为prod
 * 2、后注册Bean配置类,不然会报Bean未定义的错误
 * 3、刷新容器
 */
 context.getEnvironment().setActiveProfiles("prod");
 context.register(ProfileConfig.class);
 context.refresh();
 DemoBean demoBean = context.getBean(DemoBean.class);
​
 System.out.println(demoBean.getContent());
​
 context.close();
 }
}

Profile 可以是不同环境有不同的配置,对于自己本地开发demo项目也是可以使用的,我之前开发一个项目时,每次部署时都需要去改一下配置文件甚是着急,如果使用了profile,就会省去很多工作量。

2、Condition的使用

需要初始化类对于的接口

public interface ListService {
​
 /**
 * 不同操作系统环境下的命令
 * @return  操作系统命令
 */
 public String showListCmd();
}

接口对于的两个类

public class WindowsListService implements ListService {
 @Override
 public String showListCmd() {
 return "dir";
 }
}
public class LinuxListService implements ListService {
 @Override
 public String showListCmd() {
 return "ls";
 }
}

根据添加创建的bean

import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
​
/**
 * @description: 判断条件定义,判断Windows的条件
 *
 * @author: Shenshuaihu
 * @version: 1.0
 * @data: 2019-05-30 23:12
 */
public class WindowsCondition implements Condition {
​
 /**
 * 如果返回的为True,改内容会被创建
 * @param conditionContext
 * @param annotatedTypeMetadata
 * @return
 */
 @Override
 public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
 return conditionContext.getEnvironment().getProperty("os.name").contains("Windows");
 }
}
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
​
/**
 * @description: 判断添加定义,判断Linux的条件
 *
 * @author: Shenshuaihu
 * @version: 1.0
 * @data: 2019-05-30 23:15
 */
public class LinuxCondition implements Condition {
 @Override
 public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
 return conditionContext.getEnvironment().getProperty("os.name").contains("Linux");
 }
 }

核心配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
​
/**
 * @description:    配置类
 * @author: Shenshuaihu
 * @version: 1.0
 * @data: 2019-05-30 23:20
 */
@Configuration
@ComponentScan("com.ch3.conditional")
public class ConditionConfig {
​
 /**
 * 通过 @Conditional 符号Windows条件则实例化 windowsListService
 *
 * @return
 */
 @Bean
 @Conditional(WindowsCondition.class)
 public ListService windowsListService() {
 return new WindowsListService();
 }
​
 @Bean
 @Conditional(LinuxCondition.class)
 public ListService linuxListService() {
 return new LinuxListService();
 }
}

测试启动类

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
​
/**
 * @description:
 * @author: Shenshuaihu
 * @version: 1.0
 * @data: 2019-05-30 23:22
 */
public class ConditionMain {
 public static void main(String[] args) {
​
 AnnotationConfigApplicationContext context =
 new AnnotationConfigApplicationContext(ConditionConfig.class);
​
 ListService listService = context.getBean(ListService.class);
 System.out.println(context.getEnvironment().getProperty("os.name")
 + " 系统下的列表命令为: "
 + listService.showListCmd()
 );
 }
}

对于LinuxCondition类 继承了Condition,重写matches方法,如果返回true则可以创建该类,可以是在不同的环境实现不同的方法,或者是当存在什么属性时则可以实例化,特定的方法。

使用场景就不赘述了,读者可以自行配置使用。

参考相关的文章:

Spring - Profile

Spring profile 实现开发,测试,部署等不同环境中间的配置切换【原创】

2019/6/1 晚 于成都

转载于:https://www.jianshu.com/p/1d96508085ff

猜你喜欢

转载自blog.csdn.net/weixin_33750452/article/details/91081956