看到Profile这个关键字,或许你从来没有正眼瞧过他,又或者脑海中有些模糊的印象,比如除了这里Springmvc中的Profile,maven中也有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,我们就多了一种选择,一种更加智能省心的配置方式。通过Profile配置,Spring可以在根据环境在运行阶段来决定bean的创建与否,先举例如下,主要从Profile bean的配置和激活来展开。

Profile bean的配置

  通过注解@Profile配置

  对于上面比方中的第一种情况,在开发环境中我们配置一个数据源可能是这样的

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

  这里会使用EmbeddedDatabaseBuilder创建一个嵌入式数据库,模式定义在类文件下的schema.sql文件中

  schema.sql

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

  这里定义了一张Things表包含了两个字段

  除了模式文件,还需要通过test-data.sql加载测试数据

  test-data.sql

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

  对于这个@Bean完全不知道是放在开发的环境下创建还是产品的环境下。所以我们这里可以使用注解@Profile帮助我们为这个bean打上标识。

  从Spring 3.1版本中就引入了bean profile的功能,可以让你将不同的bean定义到一个或者多个profile里,然后在部署应用时告知要激活那个profile,则相应的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标记为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.springframework.org/schema/jeehttp://www.springframework.org/schema/jee/spring-jee.xsdhttp://www.springframework.org/schema/jdbchttp://www.springframework.org/schema/jdbc/spring-jdbc.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><beans profile="dev"><jdbc:embedded-database id="dataSource" 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 id="dataSource"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设置的值。当然,如果两者都没有设置的话,则只会创建那些定义在相应的profile中的bean。

  设置这两个属性的方式有很多:

    作为DispactcherServlet的初始化参数

    作为Web应用上下文参数

    作为JNDI条目

    作为环境变量

    作为JVM的系统属性

    在集成测试类上,使用@ActiveProfiles注解设置

  比如我们在web.xml中可以声明代码如下

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

  另外对于测试,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 {@Autowiredprivate DataSource dataSource;@Testpublic void shouldBeEmbeddedDatasource() {assertNotNull(dataSource);JdbcTemplate jdbc = new JdbcTemplate(dataSource);List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() {@Overridepublic 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 {@Autowiredprivate DataSource dataSource;@Testpublic void shouldBeEmbeddedDatasource() {// should be null, because there isn't a datasource configured in JNDIassertNull(dataSource);}}@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:datasource-config.xml")@ActiveProfiles("dev")public static class DevDataSourceTest_XMLConfig {@Autowiredprivate DataSource dataSource;@Testpublic void shouldBeEmbeddedDatasource() {assertNotNull(dataSource);JdbcTemplate jdbc = new JdbcTemplate(dataSource);List<String> results = jdbc.query("select id, name from Things", new RowMapper<String>() {@Overridepublic 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;@Testpublic void shouldBeEmbeddedDatasource() {// should be null, because there isn't a datasource configured in JNDIassertNull(dataSource);}}}

 

 运行shouldBeEmbeddedDatasource方法,测试通过

  如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!如果您想持续关注我的文章,请扫描二维码,关注JackieZheng的微信公众号,我会将我的文章推送给您,并和您一起分享我日常阅读过的优质文章。

转载于:https://www.cnblogs.com/bigdataZJ/p/SpringInAction4.html

Spring实战——Profile相关推荐

  1. 《spring实战第四版》的读书笔记

    <spring实战第四版>的读书笔记 1 概述 <Spring实战第四版>描述了Spring4架构的设计,看完了以后,最大感觉是Spring的IOC与aop理念实在是太强大了, ...

  2. Spring实战6-利用Spring和JDBC访问数据库

    主要内容 定义Spring的数据访问支持 配置数据库资源 使用Spring提供的JDBC模板 写在前面:经过上一篇文章的学习,我们掌握了如何写web应用的控制器层,不过由于只定义了SpitterRep ...

  3. 《Spring实战》读书笔记-第3章 高级装配

    <Spring实战>是学习Spring框架的一本非常经典的书籍,之前阅读了这本书,只是在书本上写写画画,最近整理了一下<Spring实战>的读书笔记,通过博客的方式进行记录分享 ...

  4. 【Spring实战】—— 14 传统的JDBC实现的DAO插入和读取

    从这篇开始学习Spring的JDBC,为了了解Spring对于JDBC的作用,先通过JDBC传统的流程,实现一个数据库的插入和读取. 从这篇你可以了解到: 1 传统的JDBC插入和读取的过程. 2 如 ...

  5. Spring实战(第3版)

    <Spring实战(第3版) > 基本信息 原书名:Spring in Actiong(third edition) 作者: (美)Craig Walls 译者: 耿渊 张卫滨 出版社:人 ...

  6. 《Spring实战》读书笔记--SpringMVC之forward与redirect

    <Spring实战>读书笔记--SpringMVC之forward与redirect 1.forward与redirect介绍 1.1 redirect 重定向,服务器收到请求后发送一个状 ...

  7. Spring实战——缓存

    缓存 提到缓存,你能想到什么?一级缓存,二级缓存,web缓存,redis-- 你所能想到的各种包罗万象存在的打着缓存旗号存在的各种技术或者实现,无非都是宣扬缓存技术的优势就是快,无需反复查询等. 当然 ...

  8. Spring实战-雇员薪资管理系统

    Spring实战-雇员薪资管理系统 基本概述 这里使用的是Spring2.5+Hibernate3.3+Struts1.3(SSH)框架,进行整合开发,通过该案例可以了解使用SHH框架进行开发的基本操 ...

  9. 【转】Nutz | Nutz项目整合Spring实战

    http://blog.csdn.net/evan_leung/article/details/54767143 Nutz项目整合Spring实战 前言 Github地址 背景 实现步骤 加入spri ...

最新文章

  1. superset安装配置
  2. linux 查看服务器网络连接,1.3.2 查看Linux服务器的网络连接(2)
  3. [转]自定义ASP.NET MVC JsonResult序列化结果
  4. 手把手·从零开始撸Docker 系列一
  5. 禁止选择文字和文本超出显示省略号
  6. 软件测试人员必备的linux命令
  7. ROS学习笔记12(用Python写一个简单的消息发布和消息订阅)
  8. WCF Ria Service“操作失败,指定的命名链接在配置中找不到”错误解决方法
  9. UrlRewriter配置IIS支持伪静态
  10. Java小程序之你画我猜
  11. Biobank genetic data探析(三)
  12. crypto661-rabin(网鼎杯2022-未完成)
  13. python 与_Python爬取拉勾网python职位数据
  14. CENTOS上的网络安全工具(十二)走向Hadoop(4) Hadoop 集群搭建
  15. Linux系统或服务器运行Fastqc
  16. 可视化股票市场结构||沪深300股票聚类可视化
  17. vscode 运行C++
  18. 架构简析| 一种自动探索Minecraft的智能体
  19. 神经网络的前向传播与反向传播
  20. C语言实现模拟键盘输入字符串

热门文章

  1. 牛津教授吐槽DeepMind心智神经网络,还推荐了这些多智能体学习论文
  2. 波士顿动力又有新视频:机器狗要开门,人类真是拽不回来
  3. 一个基于区块链的AI平台即将ICO:这可以说是今年最潮的项目了
  4. CentOS 7 - 创建新用户
  5. JAVA常见算法题(二十五)
  6. Android事件总线(四)源码解析otto
  7. 笨办法学C 练习43:一个简单的统计引擎
  8. oracle还原数据库及遇到的问题
  9. SQL Server数据库中批量导入数据
  10. 点燃乌镇,三星已重返战场!国行版Galaxy S10最高售价10999元...