環境是抽象集成在容器中模擬應用程序環境兩個關鍵方面配置文件和屬性的抽象。
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. 附錄