Spring Profile模式示例

最近,我们介绍了Spring Profiles的概念。

此概念是针对不同部署环境的轻松配置区分符。

直接的用例(已提出)是对相关类进行注释,以便Spring根据活动的配置文件加载适当的类。

但是,这种方法可能并不总是适用于常见的用例……通常,配置密钥是相同的,并且仅值会随环境而变化。

在本文中,我想提出一种模式来支持按环境加载配置数据, 无需为每个概要文件(即针对每个环境)创建/维护多个类。

在整个文章中,假设每个部署环境的数据库定义(例如用户名或连接URL)不同,我将以数据库连接配置为例。

主要思想是使用一个类来加载配置(即,一个类用于数据库连接定义),然后将包含正确概要文件配置数据的适当实例注入其中。

为了方便和清楚起见,该过程分为三个阶段:

阶段1 :基础设施
步骤1.1 –创建一个包含所有配置数据的属性文件
步骤1.2 –为每个配置文件创建注释 步骤1.3 –确保在上下文加载期间加载了配置文件

阶段2 :实施配置文件模式
步骤2.1 –创建属性界面
步骤2.2 –为每个配置文件创建一个类 步骤2.3 –创建一个包含所有数据的抽象文件

阶段3 :使用模式
步骤3.1 –使用模式的示例

弹簧轮廓图–阶段1:基础准备

该阶段将建立使用Spring Profile和配置文件的初始基础设施。

步骤1.1 –创建一个包含所有配置数据的属性文件

假设您有一个maven风格的项目,请在src / main / resources / properties中为每个环境创建一个文件,例如:

my_company_dev.properties
my_company_test.properties
my_company_production.properties

my_company_dev.properties内容的示例:

jdbc.url = jdbc:mysql:// localhost:3306 / my_project_db
db.username = dev1
db.password = dev1 hibernate.show_sql = true

my_company_production.properties内容的示例:

jdbc.url = jdbc:mysql://10.26.26.26:3306 / my_project_db
db.username = prod1
db.password = fdasjkladsof8aualwnlulw344uwj9l34 hibernate.show_sql = false

步骤1.2 –为每个配置文件创建注释

在src.main.java.com.mycompany.annotation中为每个Profile创建注释,例如:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("DEV")
public @interface Dev {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Profile("PRODUCTION")
public @interface Production {
}

为每个配置文件创建一个枚举:
公共接口MyEnums {

public enum Profile{
DEV,
TEST,
PRODUCTION
}

步骤1.3 –确保在上下文加载期间加载了配置文件

  • 定义一个系统变量以指示代码在哪个环境中运行。
    在Tomcat中,转到$ {tomcat.di} /conf/catalina.properties并插入一行:
    profile = DEV(根据您的环境)
  • 定义一个类别以设置活动配置文件
    public class ConfigurableApplicationContextInitializer implementsApplicationContextInitializer<configurableapplicationcontext> {@Overridepublic void initialize(ConfigurableApplicationContext applicationContext) {String profile = System.getProperty("profile");if (profile==null || profile.equalsIgnoreCase(Profile.DEV.name())){applicationContext.getEnvironment().setActiveProfiles(Profile.DEV.name());   }else if(profile.equalsIgnoreCase(Profile.PRODUCTION.name())){applicationContext.getEnvironment().setActiveProfiles(Profile.PRODUCTION.name()); }else if(profile.equalsIgnoreCase(Profile.TEST.name())){applicationContext.getEnvironment().setActiveProfiles(Profile.TEST.name()); }}
    }
  • 确保在上下文加载期间加载了该类
    在项目web.xml中,插入以下内容:
    <context-param><param-name>contextInitializerClasses</param-name><param-value>com.matomy.conf.ConfigurableApplicationContextInitializer</param-value>
    </context-param>

阶段2:实施配置文件模式

此阶段利用我们之前构建的基础架构并实现配置文件模式。

步骤2.1 –创建属性界面
为您拥有的配置数据创建一个接口。
在我们的例子中,该接口将提供对四个配置数据项的访问。 所以看起来像这样:

public interface SystemStrings {String getJdbcUrl();
String getDBUsername();
String getDBPassword();
Boolean getHibernateShowSQL();
//.....

步骤2.2 –为每个配置文件创建一个类

开发配置文件示例:

@Dev //Notice the dev annotation
@Component("systemStrings")
public class SystemStringsDevImpl extends AbstractSystemStrings implements SystemStrings{public SystemStringsDevImpl() throws IOException {//indication on the relevant properties filesuper("/properties/my_company_dev.properties");} 
}

生产资料示例:

@Prouction //Notice the production annotation
@Component("systemStrings")
public class SystemStringsProductionImpl extends AbstractSystemStrings implements SystemStrings{public SystemStringsProductionImpl() throws IOException {//indication on the relevant properties filesuper("/properties/my_company_production.properties");} 
}

上面的两个类是属性文件和相关环境之间进行绑定的位置。

您可能已经注意到,这些类扩展了一个抽象类。 这项技术很有用,因此我们不需要为每个Profile定义每个getter,从长远来看,这是无法管理的,实际上,这样做是没有意义的。

蜜糖和蜂蜜位于下一步,其中定义了抽象类。

步骤2.3 –创建一个包含所有数据的抽象文件

public abstract class AbstractSystemStrings implements SystemStrings{//Variables as in configuration properties file
private String jdbcUrl;
private String dBUsername;
private String dBPassword;
private boolean hibernateShowSQL;public AbstractSystemStrings(String activePropertiesFile) throws IOException {//option to override project configuration from externalFileloadConfigurationFromExternalFile();//optional..//load relevant propertiesloadProjectConfigurationPerEnvironment(activePropertiesFile);  }private void loadProjectConfigurationPerEnvironment(String activePropertiesFile) throws IOException {Resource[] resources = new ClassPathResource[ ]  {  new ClassPathResource( activePropertiesFile ) };Properties props = null;props = PropertiesLoaderUtils.loadProperties(resources[0]);jdbcUrl = props.getProperty("jdbc.url");dBUsername = props.getProperty("db.username"); dBPassword = props.getProperty("db.password");hibernateShowSQL = new Boolean(props.getProperty("hibernate.show_sql"));  
}//here should come the interface getters....

阶段3:使用模式

您可能还记得,在前面的步骤中,我们定义了一个配置数据接口。

现在,我们将在一个类中使用该接口 ,该类每个环境需要不同的数据。

请注意,这个例子与Spring博客的例子有着关键的区别,因为现在我们不需要为每个概要文件创建一个类 ,因为在这种情况下我们在概要文件中使用相同的方法并且仅改变数据

步骤3.1 –使用模式的示例

@Configuration
@EnableTransactionManagement
//DB connection configuration class 
//(don't tell me you're still using xml... ;-)
public class PersistenceConfig {@Autowiredprivate SystemStrings systemStrings; //Spring will wire by active profile@Beanpublic LocalContainerEntityManagerFactoryBean entityManagerFactoryNg(){LocalContainerEntityManagerFactoryBean factoryBean= new LocalContainerEntityManagerFactoryBean();factoryBean.setDataSource( dataSource() );factoryBean.setPersistenceUnitName("my_pu");       JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(){{// JPA propertiesthis.setDatabase( Database.MYSQL);
this.setDatabasePlatform("org.hibernate.dialect.MySQLDialect");this.setShowSql(systemStrings.getShowSqlMngHibernate());//is set per environemnt..           }};       factoryBean.setJpaVendorAdapter( vendorAdapter );factoryBean.setJpaProperties( additionalProperties() );return factoryBean;}
//...
@Beanpublic ComboPooledDataSource dataSource(){ComboPooledDataSource poolDataSource = new ComboPooledDataSource();try {poolDataSource.setDriverClass( systemStrings.getDriverClassNameMngHibernate() );} catch (PropertyVetoException e) {e.printStackTrace();}       //is set per environemnt..poolDataSource.setJdbcUrl(systemStrings.getJdbcUrl());poolDataSource.setUser( systemStrings.getDBUsername() );poolDataSource.setPassword( systemStrings.getDBPassword() );//.. more properties...       return poolDataSource;}
}

我将不胜感激和改进。
请享用!

参考: Gal Levinsky博客博客中来自JCG合作伙伴 Gal Levinsky的Spring Profile模式 。


翻译自: https://www.javacodegeeks.com/2012/08/spring-profile-pattern-example_7.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371865.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 样式 (style) 和主题(theme)

转载&#xff1a;https://gold.xitu.io/post/58441c48c59e0d0056a30bc2 样式和主题 样式是指为 View 或窗口指定外观和格式的属性集合。样式可以指定高度、填充、字体颜色、字号、背景色等许多属性。 样式是在与指定布局的 XML 不同的 XML 资源中进行定义。 Android 中的样式与…

自定义控件_VIewPager显示多个Item

一直以来想搞明白这个不完全的VIewPager是怎么做到的&#xff0c;有幸看到这片篇文章 有二种实现方法 1.设置的属性 1.clipChildren属性 2.setPageMargin 3.更新Item外界面 2.重写getPageWidth public class MultiplePagerAdapter extends PagerAdapter { private List<I…

华为怎么改输入法皮肤_微信和QQ个性键盘皮肤

hello大家好&#xff0c;今天是2019年1月1号&#xff0c;祝大家新年快乐今天是新年的第一天&#xff0c;所以说给大家介绍一个好玩的&#xff0c;微信和QQ都能设置的个性的键盘皮肤&#xff0c;看下图&#xff0c;这样的个性的键盘主题怎么设置呢&#xff1f;其实很简单&#x…

EasyMock教程–入门

在本文中&#xff0c;我将向您展示EasyMock是什么&#xff0c;以及如何使用它来测试Java应用程序。 为此&#xff0c;我将创建一个简单的Portfolio应用程序&#xff0c;并使用JUnit&#xff06;EasyMock库对其进行测试。 在开始之前&#xff0c;让我们首先了解使用EasyMock的需…

synchronized内置锁

synchronized内置锁&#xff0c;如果发生阻塞&#xff0c;无法被中断&#xff0c;除非关闭jvm.因此不能从死锁中恢复。转载于:https://www.cnblogs.com/paulbai/p/6163250.html

如何加快Json 序列化?有哪些方法?

1、使用阿里的fastjson 2、可以通过去除不必要属性加快序列化。如person对象&#xff0c;有id&#xff0c;name&#xff0c;address&#xff0c;我json需要用户姓名&#xff0c;此时序列化的时候就只序列化name&#xff0c;id和address不序列化。转载于:https://www.cnblogs.co…

用金万维怎么设置路由器_家用路由器怎么设置 家庭路由器设置方法【图文】...

这里以TP-link的无线路由器为例&#xff0c;教一下怎么调试路由器上网。准备工具:网线两条&#xff0c;电脑或者手机&#xff0c;用手机的话就不需要用网线了1、用网线连接光纤猫与路由器&#xff0c;光猫的LAN1口与路由器的WAN相连。路由器的LAN任意一个口用网线连接电脑。2、…

Liferay –简单主题开发

实际上&#xff0c;Liferay的6.1版本已经走了很长一段路&#xff0c;该版本完全支持JSF和IceFaces。 我的目标是使它成为我们团队中的标准协作工具&#xff0c;因此我仍在尝试学习它的精髓。 好的软件应用程序可以解决问题&#xff0c;但是好的软件应用程序不仅可以解决问题&am…

springmvc初步配置

导包/添加依赖&#xff1a;<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.0.2.RELEASE</version> </dependency> <dependency> <groupId>org.springfram…

获取用户地理位置

1、利用h5 属性获取用户地理位置 h5的新增属性是支持用户获取地理位置的特别是手机&#xff0c;支持的情况会更好。具体写法如下 // 定位功能getLocation () {if (navigator.geolocation) {navigator.geolocation.getCurrentPosition(showPosition, showError);} else {alert(浏…

行号 设置vim_在VSCode里面配置Vim正确姿势(细节解析)

一、导论对于不用vim的人来说&#xff0c;vim简直是个噩梦&#xff0c;复杂的指令、丑陋的界面、令人头痛的配置文件&#xff0c;任何一项都足以劝退一大波人&#xff0c;但是对于已经习惯了使用vim的人来说&#xff0c;vim简直就是马良神笔&#xff0c;似乎vim除了生孩子什么都…

使用Spring 3 MVC处理表单验证

本文是有关Spring 3的系列文章的一部分。该系列的早期文章是使用Spring 3 MVC的Hello World和使用Spring 3 MVC的 Handling Forms 。 现在让我们更深入地研究Spring。 在本文中&#xff0c;我们将学习验证从表单中获取的数据。 让我们更仔细地看一下验证任务。 场景1 &#xf…

当事人角色 变更映射策略引起的问题

IBeamMDAA V2版本中&#xff0c;由于变更了 当事人角色 的继承机制&#xff0c;在添加 当事人角色时&#xff0c;为了 构建 当事人-当事人角色之间的关系&#xff0c;代码如下&#xff1a;//if (party.PartyRoles ! null && !party.PartyRoles.Contains(sysUser))//{//…

vs xxxxx nuget配置无效

重启vs转载于:https://www.cnblogs.com/zinan/p/7080668.html

巡回沙龙_美浮特全国巡回沙龙第一期结束撒花!

科技美肤&#xff0c;无龄焕变。美浮特2019全国美肤巡回沙龙第一期活动圆满结束&#xff01;优秀的小伙伴&#xff0c;雅致的茶歇环境&#xff0c;精美的甜点小食&#xff0c;理论与体验并行的肤感测试课堂……不知道是哪一个环节给大家留下了深刻的印象呢&#xff1f;首先让我…

Spring与网关的集成

这是有关Spring Integration系列的第二篇文章。 本文以我们介绍Spring Integration的第一篇文章为基础。 上下文设置 在第一篇文章中&#xff0c;我们创建了一个简单的Java应用程序&#xff0c;其中 通过频道发送了一条消息&#xff0c; 它被服务&#xff08;即POJO&#xf…

UIAutomation识别UI元素

MS UI Automation&#xff08;Microsoft User Interface Automation&#xff1a;UIA&#xff09;是随.net framework3.0一起发布的&#xff0c;虽然在如今这个几乎每天都有各种新名词、新技术出来的所谓的21世纪&#xff0c;它显得已经有些过时了。前些日子&#xff0c;正好一个…

【C++第一个Demo】---控制台RPG游戏3【登陆菜单树】

【登陆系统--树结构】 1 首先我这里设计&#xff0c;由一个基类MainMenu构建树结构&#xff0c;并实现控制台上菜单之间的切换和返回操作 1 #ifndef _UI_BASE_H_2 #define _UI_BASE_H_3 4 #include <string>5 #include <vector>6 #include"..//Marco.h"7…

不存在_施文忠 | ”存在“与“不存在”——巴蜀文明概论

海德格尔有句名言&#xff1a;“存在者存在&#xff0c;不存在者不存在&#xff01;”四川&#xff0c;一个伟大的存在&#xff0c;偏偏存在于四川的口头禅却是“不存在”。在不存在中追求存在&#xff0c;在存在中摆脱存在。六月白鹿镇&#xff0c;书院学习了《李白与海德格尔…

Spring和JSF集成:异常处理

大多数JSF开发人员都会熟悉“发生错误”页面&#xff0c;当在他们的代码某处引发意外异常时&#xff0c;该页面就会显示。 该页面在开发时确实很有用&#xff0c;但对于生产应用程序通常不是您想要的。 通常&#xff0c;在用库存JSF替换此页面时&#xff0c;您有两种选择。 您可…