스프링 프로필이란? 간단히 말하면, 프로필은 일련의 구성입니다. 다양한 프로필은 프로그램이 실행될 때 환경에 적응하는 데 사용할 프로필을 선택할 수 있습니다. 다음 글은 Spring에서 Profile의 실제 구현에 대한 관련 정보를 주로 소개합니다.
서문
Spring의 프로필 기능은 실제로 Spring 3.1부터 나왔습니다. 컨테이너 정의된 Bean의 논리적 그룹 이름입니다. 해당 프로파일이 활성화된 경우에만 해당 프로파일에 해당하는 Bean이 Spring 컨테이너에 등록됩니다.
Profile이라는 키워드를 보면 직접 본 적이 없거나 막연한 인상을 받았을 수도 있습니다. 예를 들어 여기 Springmvc의 Profile 외에 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; }
물론 프로덕션 환경 등에서도 구성이 있을 수 있습니다. 수백 송이의 꽃을 피우는 이런 종류의 구성 방법에 대해 더 말할 수 있습니까? 우리는 항상 프로필 없이 이 작업을 수행해 왔습니다.
하지만 이제 Profile을 사용하면 더 지능적이고 걱정 없는 구성 방법을 선택할 수 있습니다. Profile 구성을 통해 Spring은 환경에 따라 실행 단계에서 Bean을 생성할지 여부를 결정할 수 있으며, 주로 Profile Bean의 구성 및 활성화부터 시작되는 예입니다.
Profile bean 구성
@Profile 주석을 통한 구성
위의 예는 In 첫 번째 경우 개발 환경에서는 다음과 같이 데이터 소스를 구성합니다. 클래스 파일 아래의 Schema.sql 파일에서
schema.sql@Bean(destroyMethod = "shutdown") public DataSource embeddedDataSource() { return new EmbeddedDatabaseBuilder() .addScript("classpath:schema.sql") .addScript("classpath:test-data.sql") .build(); }
는 여기에 Things 테이블을 정의합니다. 두 개의 필드가 포함되어 있습니다.
스키마 파일 외에 test-data.sql을 통해 테스트 데이터도 로드해야 합니다.
test-data.sqlcreate table Things ( id identity, name varchar(100) );
이 @Bean이 개발 환경에서 만들어진 것인지, 제품 환경에서 만들어진 것인지는 모르겠습니다. . 따라서 여기에서 @Profile 주석을 사용하여 이 Bean에 레이블을 지정할 수 있습니다.
Bean 프로필 기능은 Spring 버전 3.1에 도입되었습니다. 이 기능을 사용하면 하나 이상의 프로필에 다양한 Bean을 정의할 수 있으며, 애플리케이션을 배포할 때 어떤 프로필을 활성화할지 알림을 받고 해당 Bean이 생성됩니다.
예를 들어 여기insert into Things (name) values ('A')
EmbedderDataSource 빈을 다음을 통해 개발 환경에서 생성할 빈으로 표시합니다.
. 참고: 1. @Profile은 클래스 수준에서 로드됩니다. 개발자 프로필이 활성화되지 않으면 클래스의 해당 Bean이 모두 생성되지 않습니다. 2. 그렇다면 현재 개발 환경이 활성화되어 있으면 @Profile을 사용하지 않는 Bean이 생성됩니다. prod 등 다른 프로파일로 표시되면 해당 Bean이 생성되지 않습니다@Profile("dev")
3. 3.2부터 @ 프로필은 클래스 레벨을 로드할 수 있을 뿐만 아니라 메소드도 로드할 수 있으며, 구체적인 코드는 다음과 같습니다
@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(); } }
단순함 외에도 xml 구성 파일에서 주석 방법을 선언할 수 있습니다. 구체적인 구성은 다음과 같습니다.
datasource-config.xml
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(); } }
여기에는 두 가지 환경과 해당 프로필이 각각 선언되어 있습니다.
프로파일 활성화프로파일을 구성했지만 해당 환경을 활성화하는 방법. 여기에는
및두 가지 속성이 필요합니다.
에 값이 할당되면이 적용되지 않습니다. spring.profile.active
에 값이 할당되지 않으면 spring.profile.default
에서 설정한 기본값이 사용됩니다. 물론, 둘 다 설정되지 않으면 해당 프로필에 정의된 Bean만 생성됩니다.
spring.profile.active
이 두 속성을 설정하는 방법은 여러 가지가 있습니다. spring.profile.default
spring.profie.active
spring.profile.default
DispatchcherServlet의 초기화 매개변수로
웹 애플리케이션 컨텍스트 매개변수로 JNDI 항목으로
환경 변수로
JVM 시스템 속성으로
통합 테스트 클래스에서 @ActiveProfiles 주석을 사용하여
을 설정합니다. 예를 들어, 우리는 웹에서 다음과 같이 .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>
이렇게 하면 시작하고 준비해야 할 환경을 지정할 수 있습니다. 해당 콩.
另外对于测试,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'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); } } }
运行shouldBeEmbeddedDatasource方法,测试通过
总结
以上就是Spring入门实战之Profile详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!