ホームページ  >  記事  >  Java  >  Springを始めるためのプロファイルを詳しく解説

Springを始めるためのプロファイルを詳しく解説

黄舟
黄舟オリジナル
2017-03-07 09:54:482001ブラウズ

春のプロフィールとは何ですか?簡単に言えば、プロファイルは一連の構成であり、プログラムの実行中に、環境に適応するために使用するプロファイルを選択できます。以下の記事では、Spring での Profile の実際の実装に関する関連情報を中心に紹介します。必要な友人は参照してください。

はじめに

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)
);

ここで Things テーブルが定義され、2 つのフィールドが含まれます

スキーマ ファイルに加えて、test-data.sql を通じてテスト データをロードする必要もあります

test-data.sql

insert into Things (name) values ('A')

この @Bean が開発で作成されたかどうかはわかりません環境または環境内の製品。したがって、ここで @Profile アノテーションを使用して、この Bean にラベルを付けることができます。

Bean プロファイル機能は Spring バージョン 3.1 で導入されました。これにより、さまざまな Bean を 1 つ以上のプロファイルに定義し、アプリケーションのデプロイ時にどのプロファイルをアクティブ化するかを指定できるようになり、対応する Bean が作成されます。

例は次のとおりです

@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設定ファイルによる設定

単純なアノテーションメソッドに加えて、XML設定ファイルで宣言することもできます。 follow

datasource-config.xml

package 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&#39;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&#39;t a datasource configured in JNDI
 assertNull(dataSource);
 }
 }

}

2 つの環境と対応するプロファイルがここで宣言されています。

プロファイルの有効化🎜🎜🎜プロファイルを設定しましたが、対応する環境を有効化する方法。ここでは、spring.profile.activespring.profile.default の 2 つのプロパティが必要です。 🎜🎜spring.profile.active が割り当てられている場合、spring.profie.active の場合、spring.profile.default は有効になりません。値が割り当てられていない場合は、spring.profile.default で設定されたデフォルト値が使用されます。もちろん、どちらも設定されていない場合は、対応するプロファイルで定義されている Bean のみが作成されます。 🎜🎜🎜これら 2 つのプロパティを設定するには、さまざまな方法があります: 🎜🎜🎜 DispactcherServlet の初期化パラメータとして 🎜🎜 Web アプリケーションのコンテキスト パラメータとして 🎜🎜 JNDI エントリとして 🎜🎜 環境変数として 🎜🎜 JVM のシステム プロパティとして 🎜🎜 統合内クラスで @ActiveProfiles アノテーション設定を使用します🎜🎜たとえば、Web では次のようにコードを宣言できます。 🎜

另外对于测试,spring为什么提供了一个简单的注解可以使用@ActiveProfiles,它可以指定运行测试的时候应该要激活那个profile。比如这里的测试类DevDataSourceTest

package 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&#39;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&#39;t a datasource configured in JNDI
 assertNull(dataSource);
 }
 }

}

运行shouldBeEmbeddedDatasource方法,测试通过

总结

 以上就是Spring入门实战之Profile详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!



声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。