前書き
Spring の Profile 関数は、実際には Spring 3.1 の時点でリリースされており、Spring コンテナーで定義した Bean の論理グループ名として理解できます。プロファイル内の対応する Bean が Spring コンテナに登録されますか。
Profile というキーワードを見たとき、おそらくそれを直接見たことがないか、漠然とした印象を頭の中に持っているかもしれません。たとえば、ここで Springmvc の Profile に加えて、Maven にも Profile タグがあります。
文字通りに言うと、プロファイルはプロファイルを意味しますが、プロファイル機能はどのような状況で使用されますか?プロファイルの具体的な意味は何ですか?
たとえば、データベース構成の問題については、開発の観点から、組み込みデータベースを使用することができます。テスト データをロードします (コード例は後で示します)。ただし、テストの観点からは、このようにデータベース接続プールが装備されている可能性があります
@Bean(destroyMethod="close") public DataSource dataSource () { BasicDataSource dataSource = new BasicDataSource(); dataSource.setUrl("jdbc:h2:tcp://dbserver/~/test"); dataSource.setDriverClassName("org.h2.Driver"); dataSource.setUsername("sa"); dataSource.setPassword("password"); dataSource.setInitialSize(20); dataSource.setMaxActive(30); return dataSource; }
もちろん、本番環境などの構成もあります。百の花を咲かせるこの種の構成方法について、他に何が言えるでしょうか? この一連の環境に対応する構成ファイルをサイレントにデプロイするという方法は、常にプロファイルを使用せずに行われてきました。
しかし、プロファイルを使用することで、よりインテリジェントで安心な設定方法という選択肢が 1 つ増えました。プロファイル設定を通じて、Spring は環境に応じて実行フェーズ中に Bean を作成するかどうかを決定できます。以下に例を示します。主にプロファイル Bean の設定とアクティブ化から始まります。
プロファイル Bean の設定
アノテーション @Profile による設定
上記の例の最初のケースでは、開発環境で次のようなデータ ソースを設定します
@Bean(destroyMethod = "shutdown") public DataSource embeddedDataSource() { return new EmbeddedDatabaseBuilder() .addScript("classpath:schema.sql") .addScript("classpath:test-data.sql") .build(); }
ここEmbeddedDatabaseBuilder を使用して埋め込みデータベースを作成します。スキーマはクラス ファイルの下の schema.sql ファイルで定義されます
create table Things ( id identity, name varchar(100) );
スキーマ ファイルに加えて、test-data.sql を通じてテスト データをロードする必要もあります
test-data.sql
insert into Things (name) values ('A')
例は次のとおりです
@Configuration @Profile("dev") public class DevelopmentProfileConfig { @Bean(destroyMethod = "shutdown") public DataSource embeddedDataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript("classpath:schema.sql") .addScript("classpath:test-data.sql") .build(); } }
@Profile("dev")
を使用して、EmbedderDataSource Bean を開発環境で作成される Bean としてマークします。 注: 1. @Profile はクラス レベルでロードされます。開発プロファイルがアクティブ化されていない場合、クラス内のすべての対応する Bean は作成されません。 @Profile("dev")
为EmbedderDataSource bean标记为dev环境下要创建的bean。
注意:1. @Profile被加载类级别上,如果dev profile没有被激活,那么类中对应的所有bean就不会被创建
2. 如果当前是dev环境被激活了,那么对于没有使用@Profile的bean都会被创建,被标记为其他的profile如prod,则不会创建相应的bean
3. 从3.2开始@Profile不仅仅可以加载类级别上,还可以加载方法上,具体代码如下
package com.myapp; 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; import org.springframework.jndi.JndiObjectFactoryBean; @Configuration public class DataSourceConfig { @Bean(destroyMethod = "shutdown") @Profile("dev") public DataSource embeddedDataSource() { return new EmbeddedDatabaseBuilder() .setType(EmbeddedDatabaseType.H2) .addScript("classpath:schema.sql") .addScript("classpath:test-data.sql") .build(); } @Bean @Profile("prod") public DataSource jndiDataSource() { JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean(); jndiObjectFactoryBean.setJndiName("jdbc/myDS"); jndiObjectFactoryBean.setResourceRef(true); jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class); return (DataSource) jndiObjectFactoryBean.getObject(); } }
通过xml配置文件配置
除了简单的注解方式,我们哈可以通过在xml配置文件中声明的方式,具体配置如下
datasource-config.xml
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation=" http://www.php.cn/ http://www.php.cn/ http://www.php.cn/ http://www.php.cn/ http://www.php.cn/ http://www.php.cn/"> <beans profile="dev"> <jdbc:embedded-database type="H2"> <jdbc:script location="classpath:schema.sql" /> <jdbc:script location="classpath:test-data.sql" /> </jdbc:embedded-database> </beans> <beans profile="prod"> <jee:jndi-lookup lazy-init="true" jndi-name="jdbc/myDatabase" resource-ref="true" proxy-interface="javax.sql.DataSource" /> </beans> </beans>
这里分别声明了两种环境以及对应的profile。
profile激活
虽然我们已经配置好了profile,但是如何激活相应的环境呢。这里我们需要两个属性spring.profile.active
以及spring.profile.default
。
如果spring.profile.active
被赋值了,则spring.profile.default
就不会起作用,如果spring.profie.active
没有赋值,则使用默认的spring.profile.default
2. 開発環境が現在アクティブ化されている場合、使用しない @Profile Bean は作成されます。prod などの他のプロファイルとしてマークされている場合、対応する Bean は作成されません
3. 3.2 以降、@Profile はクラス レベルでロードできるだけでなく、クラス レベルでもロードできるようになりました。メソッドレベルは次のとおりです
<?xml version="1.0" encoding="UTF-8"?> <web -app version="2.5" ...> //为上下文设置默认的profile <context-param> <param-name>spring.profile.default</param-name> <param-value>dev</param-value> </context-param> ... <servlet> ... //为Serlvet设置默认的profile <init-param> <param-name>spring-profiles.default</param-name> <param-value>dev</param-value> </init-prama> ... <web-app>
単純なアノテーションメソッドに加えて、XML設定ファイルで宣言することもできます。 follow
datasource-config.xmlpackage profiles; import static org.junit.Assert.*; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; import com.myapp.DataSourceConfig; public class DataSourceConfigTest { @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=DataSourceConfig.class) @ActiveProfiles("dev") public static class DevDataSourceTest { @Autowired private DataSource dataSource; @Test public void shouldBeEmbeddedDatasource() { assertNotNull(dataSource); JdbcTemplate jdbc = new JdbcTemplate(dataSource); List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() { @Override public String mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getLong("id") + ":" + rs.getString("name"); } }); assertEquals(1, results.size()); assertEquals("1:A", results.get(0)); } } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes=DataSourceConfig.class) @ActiveProfiles("prod") public static class ProductionDataSourceTest { @Autowired private DataSource dataSource; @Test public void shouldBeEmbeddedDatasource() { // should be null, because there isn't a datasource configured in JNDI assertNull(dataSource); } } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:datasource-config.xml") @ActiveProfiles("dev") public static class DevDataSourceTest_XMLConfig { @Autowired private DataSource dataSource; @Test public void shouldBeEmbeddedDatasource() { assertNotNull(dataSource); JdbcTemplate jdbc = new JdbcTemplate(dataSource); List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() { @Override public String mapRow(ResultSet rs, int rowNum) throws SQLException { return rs.getLong("id") + ":" + rs.getString("name"); } }); assertEquals(1, results.size()); assertEquals("1:A", results.get(0)); } } @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:datasource-config.xml") @ActiveProfiles("prod") public static class ProductionDataSourceTest_XMLConfig { @Autowired(required=false) private DataSource dataSource; @Test public void shouldBeEmbeddedDatasource() { // should be null, because there isn't a datasource configured in JNDI assertNull(dataSource); } } }
2 つの環境と対応するプロファイルがここで宣言されています。
プロファイルの有効化プロファイルを設定しましたが、対応する環境を有効化する方法。ここでは、spring.profile.active
と spring.profile.default
の 2 つのプロパティが必要です。
spring.profile.active
が割り当てられている場合、spring.profie.active
の場合、spring.profile.default
は有効になりません。値が割り当てられていない場合は、spring.profile.default
で設定されたデフォルト値が使用されます。もちろん、どちらも設定されていない場合は、対応するプロファイルで定義されている Bean のみが作成されます。
Spring のプロフィールに関するさらに詳しい記事については、PHP 中国語 Web サイトをご覧ください。