环境是抽象集成在容器中模拟应用程序环境两个关键方面配置文件和属性的抽象。
profile: 命名规则, bean命令逻辑组
Properties: 包括属性文件,JVM系统属性,系统环境变量, JNDI, servlet上下文参数,ad-hoc属性对象,等
1.31.1 Bean定义配置文件
bean definition profiles是核心容器的一种机制, 运行在不同的环境定义不同的bean.
environment可以让不同的用户使用不同的东西, 包括:
- 在开发中使用内存数据源, 在测试和正式环境中从JNDI使用同样的datasource
- 仅在部署到性能环境中注册监视框架。
- 为客户A或客户B部署注册bean的自定义实现
以数据源的使用为例, 在测试环境中:
开发环境:
/**
* @Title: StandaloneDataConfig.java
* @Package com.oscar999.chp13
* @Description: TODO
* @author oscar999
* @date Sep 3, 2018 9:56:37 AM
* @version V1.0
*/
package com.oscar999.chp13;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
/**
* @ClassName: StandaloneDataConfig
* @Description: TODO
* @author oscar999
*/
@Configuration
@Profile("development")
public class StandaloneDataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("my-schema.sql")
.addScript("my-test-data.sql").build();
}
}
测试或正式环境
/**
* @Title: JndiDataConfig.java
* @Package com.oscar999.chp13
* @Description: TODO
* @author oscar999
* @date Sep 3, 2018 10:10:24 AM
* @version V1.0
*/
package com.oscar999.chp13;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
/**
* @ClassName: JndiDataConfig
* @Description: TODO
* @author oscar999
*/
@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");
}
}
两个写在同一个类里:
/**
* @Title: AppConfig.java
* @Package com.oscar999.chp13
* @Description: TODO
* @author oscar999
* @date Sep 3, 2018 10:16:39 AM
* @version V1.0
*/
package com.oscar999.chp13;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
/**
* @ClassName: AppConfig
* @Description: TODO
* @author oscar999
*/
@Configuration
public class AppConfig {
@Bean("dataSource")
@Profile("development")
public DataSource standaloneDataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript("my-schema.sql")
.addScript("my-test-data.sql").build();
}
@Bean("dataSource")
@Profile("production")
public DataSource jndiDataSource() throws Exception {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
}
}
@Profile("production")也可以使用 @Production 替换, 定义注解接口。
/**
* @Title: Production.java
* @Package com.oscar999.chp13
* @Description: TODO
* @author oscar999
* @date Sep 3, 2018 10:14:21 AM
* @version V1.0
*/
package com.oscar999.chp13;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.context.annotation.Profile;
/**
* @ClassName: Production
* @Description: TODO
* @author oscar999
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("production")
public @interface Production {
}
激活配置
使用哪一种配置的激活方式:
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
c
ctx.getEnvironment().setActiveProfiles("development");
c
ctx.register(SomeConfig.class, StandaloneDataConfig.class, JndiDataConfig.class);
c
ctx.refresh();
也可以激活多个
ctx.getEnvironment().setActiveProfiles("profile1", "profile2");
以下配置也可以
-Dspring.profiles.active="profile1,profile2"
默认配置
@Profile("default")
可以设置 spring.profiles.default 或是setDefaultProfiles()方法设置默认的。
1.13.2 PropertySource 抽象
Spring环境抽象提供了搜索可配置层级属性的操作。
ApplicationContext ctx = new GenericApplicationContext();
E
Environment env = ctx.getEnvironment();
boolean containsFoo = env.containsProperty("foo");
System.out.println("Does my environment contain the 'foo' property? " + containsFoo);
StandardServletEnvironment,按以下查找以下:
- ServletConfig 参数,比如DispatcherServlet 的上下文
- ServletContext 参数, web.xml中context-param
- JNDI 环境变量。 java:comp/env/
- JVM系统变量, 使用-D 命名行参数
- JVM系统环境- 操作系系统环境变量
也可以自己添加PropertySources
ConfigurableApplicationContext ctx = new GenericApplicationContext();
M
MutablePropertySources sources = ctx.getEnvironment().getPropertySources();
s
sources.addFirst(new MyPropertySource());
1.13.3 @PropertySource
@PropertySource注解提供了一个方便的添加PropertySource到Spring环境的方式。
假如app.properties包含了键值对的对应,类似:
testbean.name=myTestBean
@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;
}
}
}
任何类似${…}在资源路径的占位符将被已经注册在环境中的值替换。
@Configuration
@PropertySource("classpath:/com/${my.placeholder:default/path}/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
}
1.13.4 占位符处理
一般而言,占位符元素会被JVM系统变量或是环境变量替换。但是,环境抽象集成在这个容器里, 很容易处理占位符。
<beans>
<import resource="com/bank/service/${customer}-config.xml"/>
</beans>
- 空白目录
- 0.环境准备
- 0.1基于maven的工程创建
- 1.控制反转容器
- 1.1 Spring控制反转容器和beans介绍
- 1.2 容器概览
- 1.3 Bean概览
- 1.4 依赖
- 1.5 Bean的范围
- 1.6 客制bean的特性
- 1.7 Bean定义的继承
- 1.8 容器扩展点
- 1.9 基于注解的容器配置
- 1.10 类路径扫描及组件管理
- 1.11 使用JSR 330标准的注解
- 1.12 基于Java的容器配置
- 1.12.1 基本概念: @Bean 和 @Configuration
- 1.13 环境抽象化
- 1.14 注册一个LoadTimeWeaver
- 1.15 ApplicationContext的附加功能
- 1.16 BeanFactory
- 2. 资源
- 3. 验证,数据绑定和类型转换
- 4. Spring表达式语言(SpEL)
- 5. Spring面向方面的切面编程
- 6. Spring AOP 接口
- 7. 空安全
- 8. 数据缓冲和编码
- 9. 附录