Original address: Http://www.summa.com/blog/2009/04/20/6-tips-for-managing-property-files-with-spring
What could is simpler than property files? In a enterprise application, it turns out, many things! In this post I'll take a look at a few subtle complexities to managing properties in an enterprise Java Spring application , and hopefully demonstrate how a little fore-thought in design can yield big savings in terms of time, confusion, bugs, a nd gray hair down the road.
Types of Properties
Before designing an approach-managing property files, it's critical first to understand the types of Propertie S is to be managed. Here is four characteristics to consider:
- is some properties Environment specific –in other words, does they have a diff Erent value in one environment than another? For example, a database connection string would differ in the TEST environment than it would the PROD environment.
- do any properties contain sensitive information , like passwords or credentials, which can ' t sit In plain text in the deployment unit (e.g. WAR, EAR)?
- do any properties need to is located external from the deployment unit (e.g. on the file Sy Stem rather than in the WAR, perhaps to being managed by a systems administrator)?
- should properties be Dynamic , in the sense this they can be updated at runtime (i.e. without req Uiring A restart of the application)?
Each of these special characteristics adds a degree of complexity to applications-necessitating additional Infrastructur E Beyond the simple Java Properties class.
Spring ' s Propertyplaceholderconfigurer
Fortunately for us, the Spring framework, with the Propertyplaceholderconfigurer and Propertyoverrideconfigurer, provides The features and hooks we need to manage these cases (with the exception "dynamic" properties). And true to their philosophy, Spring makes simple things simple, and complicated things possible.
The Propertyplaceholderconfigurer allows properties to being pulled in to the application context file. For example, in the simplest case, a property "Db.user" defined in Database.properties could is pulled into the ${db.user} Placeholder
<bean id= "Propertyplaceholderconfigurer"
class= "Org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" >
<property name= "Locations" >
<list>
<value>classpath:database.properties</value>
</list>
</property>
</bean>
<bean id= "DataSource" class= "Com.mchange.v2.c3p0.ComboPooledDataSource" >
<property name= "user" value= "${db.user}"/>
<property name= "Password" value= "${db.password}"/>
...
</bean>
The Propertyoverrideconfigurer works in the opposite-in-the-pushing properties from files to properties in the CO ntext file (without have to specifically define a place holder–e.g. ${db.user}). These is both well documented in the Spring API and documentation.
Tips
Given the different possible types of properties, and Spring ' s property framework, here is a few tips for managing them:
1) Consider using a JVM System Property This sets the environment of the machine (e.g. "my.env=test"), telling th e Configurer which property file to use. For example:
<context:property-placeholder location= "Classpath:db-${my.env}.properties"/>
If the "My.env" property is set to "TEST" and then obviously the propertyplacementconfigurer would look for a file called "D B-test.properties ". For Tomcat, this property can is set in the admin console or defined in a startup script (e.g. "-dmy.env=test")-neither of which is very elegant. Alternatively, it is possible-use JNDI with Tomcat, defining ' my.env ' in the Server.xml and the context.xml of the Web App. (Note, there is of course many other ways to solve this environment-specific problem, it is a easy and relati Vely Straight-forward one.)
2) It may is necessary to set the ignoreunresolvableplaceholders to True for any propertyplaceholderconfigurer, W Hich would ensure that a configurer won ' t-fail if it can ' t find a property. Why would this is a good thing? Oftentimes, one context file would import the other context files, and the May has their own configurer. If Ignoreunresolvableplaceholders is set to False (the default) and then one configure would fail if it couldn ' t find the Pro Perty, even if another configurer down-stream could find it (see good explanation here). Beware, however, since this would suppress warnings for legitimate missing properties, making for some tough-to-debug confi Guration problems.
3) to encrypt properties, subclass the Propertyplacementconfigurer and override the Convertpropertyvalue () Metho D. For example:
Protected string Convertpropertyvalue (String strval) { //if strval starts with "!!" then return Encryptutil.decrypt (s Trval) //Else return Strval}
4) Consider using the Systempropertiesmode property of the Configurer to override properties defined in property Files with System properties. For one-off environment specific properties This can is a helpful solution, however, for defining many properties, this co Nfiguration can be cumbersone.
5) For properties This need to is managed outsideof the WAR, consider using a System property to define Where the file is located. For example, the property ${ext.prop.dir} could define some default directory in the file system where external property F Iles is kept:
<context:property-placeholder location= "File:///${ext.prop.dir}db.properties"/>
This entails, however, which this property is set for any process that leverages the Spring container (e.g. add the Param t o the Run configurationfor integration/unit tests, etc), otherwise the file would not be found. This can is a pain. To circumvent, the Configurer can is overridden–changing the behavior such that it looks to the external directory only If the System is set, otherwise it pulls from the classpath.
6) Beware of redundancy of environment-specific properties. For example, if the solution are to has one property of file for each environment (e.g. "db-test.properties", "Db-dev.propert IES ", etc), then maintaining these properties can be a bit of a nightmare-if a property" foo "was added, then it would h Ave to is added to the property file for each environment (e.g. DEV, TEST, PROD, etc). The propertyoverrideconfigurer is appropriate to eliminate this redundancy, setting the default value in the application C Ontext itself, but then the overriding value in a separate file. It's important, however, to-document this well, since it can look a bit "magical" to an unsuspecting maintenance developer Who sees one value specified in the context file, but another used at runtime.
Conclusion
Managing properties for the enterprise application is a little trickier than one might expect. With Spring's property configurers, however, the toughest part was just knowing what you need-the rest comes out of the B Ox, or with some minor extensions.
Hopefully a few of these tips would be useful for you. Please let me know some of your own!
6-tips-for-managing-property-files-with-spring--turn