本質上你有一個完成的JAR,你想放到另一個環境中,並且沒有任何修改就可以在運行時選擇合適的屬性。如果這是正確的,那麼以下方法是有效的:
1)依賴用戶主目錄中的屬性文件的存在。
配置PropertyPlaceholderConfigurer引用屬性文件外部JAR這樣的:
<bean id="applicationProperties" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="false"/>
<property name="order" value="1"/>
<property name="locations">
<list>
<!-- User home holds secured information -->
<value>file:${user.home}/MyApp/application.properties</value>
</list>
</property>
</bean>
操作系統將確保application.properties文件的內容,因此只有合適的人可以訪問它。由於在第一次運行應用程序時此文件不存在,因此請創建一個簡單的腳本,用於在啓動時向用戶詢問臨界值(例如,用戶名,密碼,Hibernate方言等)。爲命令行界面提供廣泛的幫助和合理的默認值。 2)如果您的應用程序處於受控環境中以便可以看到數據庫,那麼可以將問題簡化爲使用上面的技術1)創建基本憑據以在上下文啓動期間連接到數據庫,然後執行使用通過JDBC讀取的值進行替換。您將需要一個兩階段的方法來啓動應用程序:第1階段通過application.properties文件調用父上下文,該文件填充JdbcTemplate和關聯的DataSource;階段2調用引用父代的主要上下文,以便可以像在JdbcPropertyPlaceholderConfigurer中配置一樣使用JdbcTemplate。
這種代碼的一個例子是這樣的:
public class JdbcPropertyPlaceholderConfigurer extends PropertyPlaceholderConfigurer {
private Logger log = Logger.getLogger(JdbcPropertyPlaceholderConfigurer.class);
private JdbcTemplate jdbcTemplate;
private String nameColumn;
private String valueColumn;
private String propertiesTable;
/**
* Provide a different prefix
*/
public JdbcPropertyPlaceholderConfigurer() {
super();
setPlaceholderPrefix("#{");
}
@Override
protected void loadProperties(final Properties props) throws IOException {
if (null == props) {
throw new IOException("No properties passed by Spring framework - cannot proceed");
}
String sql = String.format("select %s, %s from %s", nameColumn, valueColumn, propertiesTable);
log.info("Reading configuration properties from database");
try {
jdbcTemplate.query(sql, new RowCallbackHandler() {
public void processRow(ResultSet rs) throws SQLException {
String name = rs.getString(nameColumn);
String value = rs.getString(valueColumn);
if (null == name || null == value) {
throw new SQLException("Configuration database contains empty data. Name='" + name + "' Value='" + value + "'");
}
props.setProperty(name, value);
}
});
} catch (Exception e) {
log.fatal("There is an error in either 'application.properties' or the configuration database.");
throw new IOException(e);
}
if (props.size() == 0) {
log.fatal("The configuration database could not be reached or does not contain any properties in '" + propertiesTable + "'");
}
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setNameColumn(String nameColumn) {
this.nameColumn = nameColumn;
}
public void setValueColumn(String valueColumn) {
this.valueColumn = valueColumn;
}
public void setPropertiesTable(String propertiesTable) {
this.propertiesTable = propertiesTable;
}
}
以上將隨後在春天像這樣被配置(注意順序財產而來的通常$前綴佔位符後):
<!-- Enable configuration through the JDBC configuration with fall-through to framework.properties -->
<bean id="jdbcProperties" class="org.example.JdbcPropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="false"/>
<property name="order" value="2"/>
<property name="nameColumn" value="name"/>
<property name="valueColumn" value="value"/>
<property name="propertiesTable" value="my_properties_table"/>
<property name="jdbcTemplate" ref="configurationJdbcTemplate"/> <!-- Supplied in a parent context -->
</bean>
這將允許在Spring配置
<!-- Read from application.properties -->
<property name="username">${username}</property>
...
<!-- Read in from JDBC as part of second pass after all $'s have been fulfilled -->
<property name="central-thing">#{name.key.in.db}</property>
發生後續3)當然,如果你在一個Web應用程序容器中,那麼你只需要使用JNDI。但你並不是你所不能的。
希望這會有所幫助!
感謝構建時間建議,但它不適用於我的情況。我已經更新了我的問題以反映這一點;我的意思是最初包含這些信息並且忘記了。我會檢查你的其他建議。 – Ickster
我使用Maven作爲構建工具。在maven打包時,你如何捆綁正確的配置。 – premcs