Spring系列.Environment接口
Environment 接口介绍
在 Spring 中,Environment 接口主要管理应用程序两个方面的内容:profile 和 properties。
profile 可以简单的等同于环境,比如说平时项目中常见的环境有开发(dev)、测试(stg)和生产(prod),Spring 启动的时候可以设置激活具体的环境。当然,这个 profile 我们还可以为其赋予很多含义,这个主要看你的业务。比如说,你开发的软件会交付给客户A,也会交付给客户B,那么这个 profile 也可以定义成客户的含义。
properties 是配置,配置的来源有很多,可以是配置文件、JVM 的参数、系统的环境变量、JNDI、Sevlet Contxet 参数以及 Map 对象等,使用 Environment 接口,可以方便的获取这些配置。
Bean Definition Profiles
使用 @Profile
Spring 容器可以根据不同的 profile 配置不同的 Bean。这个特性可以帮助你实现很多灵活的功能,比如:
- 开发环境使用内存数据库,测试和生产环境才使用关系型数据库,比如 Mysql 和 Oracle 等
- 交互给客户 A 的软件使用 A 特性,交付给客户 B 的软件使用 B 特性
@Configuration @Profile("development") public class StandaloneDataConfig { @Bean public DataSource dataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.HSQL) .addScript("classpath:com/bank/config/sql/schema.sql") .addScript("classpath:com/bank/config/sql/test-data.sql") .build(); } } @Configuration @Profile("production") public class JndiDataConfig { @Bean(destroyMethod="") public DataSource dataSource() throws Exception { Context ctx = new InitialContext(); return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource"); } }
对比上面的两个配置,我们发现 @Profile 非常适合在两个环境下,Bean 的定义完全不一样的情况,如果两个 Bean 的定义是一样的,只是一些参数不一样的话,我们完全可以使用配置文件的方式实现。
@Profile 注解后面的表达式可以是一个简单的字符串,也可以是一个逻辑运算符。@Profile 支持如下的逻辑运算符。
- !: A logical “not” of the profile
- &: A logical “and” of the profiles
- |: A logical “or” of the profiles
说明:
If a @Configuration class is marked with @Profile, all of the @Bean methods and @Import annotations associated with that class are bypassed unless one or more of the specified profiles are active. If a @Component or @Configuration class is marked with @Profile({"p1", "p2"}), that class is not registered or processed unless profiles 'p1' or 'p2' have been activated.
使用 xml 方式配置
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xsi:schemaLocation="..."> <!-- other bean definitions --> <beans profile="development"> <jdbc:embedded-database id="dataSource"> <jdbc:script location="classpath:com/bank/config/sql/schema.sql"/> <jdbc:script location="classpath:com/bank/config/sql/test-data.sql"/> </jdbc:embedded-database> </beans> <beans profile="production"> <jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/datasource"/> </beans> </beans>
激活 profile
1. API 方式
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); // 设置激活的 profile ctx.getEnvironment().setActiveProfiles("development"); ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class); ctx.refresh();
2. 命令行方式
-Dspring.profiles.active="profile1,profile2"
3. 配置文件方式
spring: profiles: active: dev
默认的 profile
Spring 默认的 profile 是 default,可以通过 Environment 的 API 进行修改。
PropertySource 接口
PropertySource 接口是对任何形式的 key-value 键值对的抽象。
@PropertySource
@PropertySource 这个注解的作用是将配置文件中的键值对放入Environment。这个注解的作用和传统配置方式中的 context:place-hold一致。
@Configuration @PropertySource("classpath:/com/myco/app.properties") public class AppConfig { @Autowired Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("testbean.name")); return testBean; } }
经过上面这样的配置,我们就可以使用 ${key} 这种形式来取变量的值。有时如果我们没配置 key 的值,Spring 会抛异常。这时我们可以使用 ${key:defaultvalue} 这种形式配置默认值。
package javaBase;import org.openqa.selenium.*;import org.openqa.selenium.chrome.ChromeDriver;import j ...