html5中文学习网

您的位置: 首页 > 网络编程 > java教程 » 正文

Spring入门实战之Profile详解_java_

[ ] 已经帮助:人解决问题

前言6S6HTML5中文学习网 - HTML5先行者学习网

Spring中的Profile功能其实早在Spring 3.1的版本就已经出来,它可以理解为我们在Spring容器中所定义的Bean的逻辑组名称,只有当这些Profile被激活的时候,才会将Profile中所对应的Bean注册到Spring容器中。6S6HTML5中文学习网 - HTML5先行者学习网

看到Profile这个关键字,或许你从来没有正眼瞧过他,又或者脑海中有些模糊的印象,比如除了这里Springmvc中的Profile,maven中也有Profile的标签。6S6HTML5中文学习网 - HTML5先行者学习网

从字面意思来看,Profile表示侧面,那什么情况下才会用到侧面这个功能呢,而侧面具体又有什么含义呢6S6HTML5中文学习网 - HTML5先行者学习网

打一个比方,对于数据库的配置问题,在开发的眼中可以使用嵌入的数据库,并且加载测试数据(后面会给出代码示例)。但是在测试的眼中,可能会配一个数据库连接池类似这样6S6HTML5中文学习网 - HTML5先行者学习网

@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这套我们一直都是这么做。6S6HTML5中文学习网 - HTML5先行者学习网

但是现在有了Profile,我们就多了一种选择,一种更加智能省心的配置方式。通过Profile配置,Spring可以在根据环境在运行阶段来决定bean的创建与否,先举例如下,主要从Profile bean的配置和激活来展开。6S6HTML5中文学习网 - HTML5先行者学习网

Profile bean的配置6S6HTML5中文学习网 - HTML5先行者学习网

通过注解@Profile配置6S6HTML5中文学习网 - HTML5先行者学习网

对于上面比方中的第一种情况,在开发环境中我们配置一个数据源可能是这样的6S6HTML5中文学习网 - HTML5先行者学习网

@Bean(destroyMethod = "shutdown")public DataSource embeddedDataSource() { return new EmbeddedDatabaseBuilder() .addScript("classpath:schema.sql") .addScript("classpath:test-data.sql") .build(); }

这里会使用EmbeddedDatabaseBuilder创建一个嵌入式数据库,模式定义在类文件下的schema.sql文件中6S6HTML5中文学习网 - HTML5先行者学习网

schema.sql6S6HTML5中文学习网 - HTML5先行者学习网

create table Things ( id identity, name varchar(100));

这里定义了一张Things表包含了两个字段6S6HTML5中文学习网 - HTML5先行者学习网

除了模式文件,还需要通过test-data.sql加载测试数据6S6HTML5中文学习网 - HTML5先行者学习网

test-data.sql6S6HTML5中文学习网 - HTML5先行者学习网

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

对于这个@Bean完全不知道是放在开发的环境下创建还是产品的环境下。所以我们这里可以使用注解@Profile帮助我们为这个bean打上标识。6S6HTML5中文学习网 - HTML5先行者学习网

从Spring 3.1版本中就引入了bean profile的功能,可以让你将不同的bean定义到一个或者多个profile里,然后在部署应用时告知要激活那个profile,则相应的bean就会被创建。6S6HTML5中文学习网 - HTML5先行者学习网

比如这里6S6HTML5中文学习网 - HTML5先行者学习网

@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标记为dev环境下要创建的bean。6S6HTML5中文学习网 - HTML5先行者学习网

注意:1. @Profile被加载类级别上,如果dev profile没有被激活,那么类中对应的所有bean就不会被创建6S6HTML5中文学习网 - HTML5先行者学习网

         2. 如果当前是dev环境被激活了,那么对于没有使用@Profile的bean都会被创建,被标记为其他的profile如prod,则不会创建相应的bean6S6HTML5中文学习网 - HTML5先行者学习网

         3. 从3.2开始@Profile不仅仅可以加载类级别上,还可以加载方法上,具体代码如下6S6HTML5中文学习网 - HTML5先行者学习网

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;@Configurationpublic 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配置文件配置6S6HTML5中文学习网 - HTML5先行者学习网

除了简单的注解方式,我们哈可以通过在xml配置文件中声明的方式,具体配置如下6S6HTML5中文学习网 - HTML5先行者学习网

datasource-config.xml6S6HTML5中文学习网 - HTML5先行者学习网

<?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.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <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。6S6HTML5中文学习网 - HTML5先行者学习网

profile激活6S6HTML5中文学习网 - HTML5先行者学习网

虽然我们已经配置好了profile,但是如何激活相应的环境呢。这里我们需要两个属性spring.profile.active以及spring.profile.default6S6HTML5中文学习网 - HTML5先行者学习网

如果spring.profile.active被赋值了,则spring.profile.default就不会起作用,如果spring.profie.active没有赋值,则使用默认的spring.profile.default设置的值。当然,如果两者都没有设置的话,则只会创建那些定义在相应的profile中的bean。6S6HTML5中文学习网 - HTML5先行者学习网

设置这两个属性的方式有很多:6S6HTML5中文学习网 - HTML5先行者学习网

作为DispactcherServlet的初始化参数6S6HTML5中文学习网 - HTML5先行者学习网

作为Web应用上下文参数6S6HTML5中文学习网 - HTML5先行者学习网

作为JNDI条目6S6HTML5中文学习网 - HTML5先行者学习网

作为环境变量6S6HTML5中文学习网 - HTML5先行者学习网

作为JVM的系统属性6S6HTML5中文学习网 - HTML5先行者学习网

在集成测试类上,使用@ActiveProfiles注解设置6S6HTML5中文学习网 - HTML5先行者学习网

比如我们在web.xml中可以声明代码如下6S6HTML5中文学习网 - HTML5先行者学习网

<?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>

这样就可以指定需要启动那种环境,并准备相应的bean。6S6HTML5中文学习网 - HTML5先行者学习网

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

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方法,测试通过6S6HTML5中文学习网 - HTML5先行者学习网

6S6HTML5中文学习网 - HTML5先行者学习网

总结6S6HTML5中文学习网 - HTML5先行者学习网

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。6S6HTML5中文学习网 - HTML5先行者学习网

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助