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.pswp.cn/news/371865.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371865.shtml
英文地址,請注明出處:http://en.pswp.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;您有兩種選擇。 您可…