原文地址在这里
http://blog.carbonfive.com/2008/04/java/configuring-applications-with-spring
If you’ve used Spring before, you’ve almost definitely used a PropertyPlaceholderConfigurer to inject settings from external sources — most likely properties files — into your application context. The most common use cases include JDBC and Hibernate settings, but it’s not that uncommon to also configure Lucene index, temp file, or image cache directories as well. The simplest case looks something like this:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:application.properties"/>
</bean>
<!-- A sample bean that needs some settings. -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
And application.properties might look like this:
jdbc.driver=org.h2.Driver
jdbc.url=jdbc:h2:mem:example
jdbc.username=sa
jdbc.password=
Note, you can achieve the same simple configuration using the new spring 2.x style schema configuration, but it doesn’t allow for any further customization so we’re going to use the old style.
<!-- Example of new Spring 2.x style -->
<context:property-placeholder location="classpath:application.properties"/>
This handles the simple case of replacing placeholders (e.g. ${jdbc.url}) with values found in a properties files (e.g. jdbc.url=jdbc:h2:mem:example). In a real-world application, we not only need to collect settings, but also override them in different environments. Many of our applications are deployed in 4 or more environments (developer machine, build server, staging server, and production), each requiring different databases at the very least.
There are a few ways to enable overriding of properties. Let’s take a look at them in turn:
1. Setting the system properties mode to override (default is fallback)
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="location" value="classpath:application.properties"/>
</bean>
When configured in this mode, any value specified as a system property to the JVM will override any values set in properties files. For example, adding -Djdbc.url=jdbc:h2:mem:cheesewhiz to the JVM arguments would override the value in the file (jdbc:h2:mem:example). On a Java 1.5 or newer platform, Spring will also look for an environment variable called jdbc.url is no system property was found.
2. Specifying an optional properties file
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>classpath:local.properties</value>
</list>
</property>
</bean>
When ignoreResourceNotFound is set to true, Spring will ignore resources that don’t exist. You can imagine application.properties, containing all of the default settings, versioned in your SCM system. Developers have the option of creating a properties file called local.properties to override any settings that differ in their environment. This file should be unversioned and ignored by your SCM system. This works because properties are loaded in order and replace previous values.
3. Web Application overrides
In a web application environment, Spring also supports specifying values in web.xml as context params or in your application server specific meta-data as servlet attributes. For example, if you’re using Tomcat you can specify one or more parameter elements in your context.xml, and Spring will can inject those values into placeholders.
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="location" value="classpath:application.properties"/>
</bean>
The ServletContextPropertyPlaceholderConfigurer conveniently works in non servlet environments by falling back to the behavior of a PropertyPlaceholderConfigurer. This is great when running unit tests.
4. Combining techniques
There’s no reason why these techniques can’t be combined. Technique #1 is great for overriding a few values while #2 is better for overriding many. #3 just expands the field of view when Spring goes to resolve placeholders. When combined, system properties override those in files. When using technique #3, there are some settings available for adjusting the override behavior (see contextOverride). Test the resolution order when combining to ensure it’s behaving as expected.
Optional External Properties
There’s another use case that applies to some projects. Often in non-developer environments, system admins want to keep properties for the environment outside of the deployable archive or the application server, and they don’t want to deal with keeping those files in a Tomcat context file; they prefer a simple properties file. They also don’t want to have to place the file in a hard-coded location (e.g. /var/acmeapp/application.properties) or they may keep configuration for multiple servers in the same network directory, each file names after the server. With a little trickery, it’s easy to support an optional external properties file that isn’t in a hard-coded location. The location of the file is passed as a single system property to the JVM, for example: -Dconfig=file://var/acmeapp/server1.properties. Here’s the configuration to make it happen:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreResourceNotFound" value="true"/>
<property name="location" value="${config}"/>
</bean>
The first definition enables basic property resolution through system properties (in fallback mode). The second bean loads the resource from the location resolved from the system property -Dconfig. All spring resource urls are supported, making this very flexible.
Putting it all together
Here’s a configuration that does more than most people would need, but allows for ultimate flexibility:
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
<bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="searchContextAttributes" value="true"/>
<property name="contextOverride" value="true"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:application.properties</value>
<value>classpath:local.properties</value>
<value>${config}</value>
</list>
</property>
</bean>
Every placeholder goes through the following resolution process. Once a value is found it’s set and the next placeholder is resolved:
1. (optional) Property value specified as a system or environment property; useful for overriding specific placeholders (e.g. -Djdbc.host=devdb / -Djdbc.username=carbon5)
2. (optional) Context parameters located in web.xml or context attributes specified in application server meta-data (e.g. a Tomcat context.xml).
3. (optional) Properties file located by the system/environment variable called “config”; useful for externalizing configuration. All URL types are supported (e.g. -Dconfig=c://hmc.properties).
4. (optional) Properties file identified by classpath:local.properties; useful for specific developer overrides.
5. (required) Properties file identified by classpath:application.properties, which contains default settings for our application.
Best Practices
* Deploy the same exact artifact (e.g. war, ear, etc) across all environments by externalizing configuration. This may seem daunting, but the emergent benefits are huge in terms of simplicity.
* Only make things that can safely change across environments configurable. Also, only things that need to be configurable should be configurable, it’s easy to go overboard.
* Configure the minimal properties search path that meets your requirements.
* When looking for properties files in the project tree, use classpath resources whenever possible. This makes finding those files easy, consistent, and insensitive to the working-dir, which is great when running tests from your IDE and command line.
* Aim for a zero-configuration check-out, build, run-tests cycle for the environment where its happens most: development.
What other interesting configuration scenarios have you seen?
分享到:
相关推荐
Getting started with Spring Framework is a hands-on guide to begin developing applications using Spring Framework. This book is meant for Java developers with little or no knowledge of Spring ...
Table of Contents Configuring a Spring Development Environment Spring Framework Fundamentals Web Application Architecture Spring MVC Architecture Implementing Controllers Implementing Controllers ...
Developers who use Spring Boot often say that they can't imagine going back to hand configuring their applications. About the Book Spring Boot in Action is a developer-focused guide to writing ...
14.1.2. Using JSR-250’s @RolesAllowed with Spring Security 14.2. Using expressions for method-level security 14.2.1. Expressing method access rules 14.2.2. Filtering method inputs and outputs 14.3. ...
Gradually, you will learn the core elements of Aspect-Oriented Programming and how to work with Spring MVC and then understand how to link to the database and persist data configuring ORM, using ...
4. Working with Spring Boot 5. Learning about Spring Boot Features 6. Moving to Production 7. Advanced Topics II. Getting Started 8. Introducing Spring Boot 9. System Requirements 9.1. Servlet ...
10. **Configuration**: Configuring MyBatis-Spring typically involves defining the SqlSessionFactoryBean and MapperFactoryBean in your Spring XML configuration, along with the necessary dependencies ...
Gradually, you will learn the core elements of Aspect-Oriented Programming and how to work with Spring MVC and then understand how to link to the database and persist data configuring ORM, using ...
You will learn about design patterns specific to applications running in the cloud and find out how you can build a microservice in Java Spring using REST APIs. You will then take a deep dive into ...
- **Sharing Configuration With All Applications**:与所有应用共享配置。 - **JDBC Backend**:JDBC后端。 - **Composite Environment Repositories**:复合环境仓库。 - **Property Overrides**:属性覆盖。...
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................
the challenge of concisely distilling the core aspects of working with Spring Boot into another cogent book. Nor is it surprising that Craig and the Manning crew have done another tremendously ...
Chapter 11: Building Applications with Spring Web Flow .................................373 Chapter 12: Advanced Spring Web Flow.............................................................429 ...
3. New Features and Enhancements in Spring Framework 4.0 ............................................ 17 3.1. Improved Getting Started Experience .........................................................
Microservices are the next big thing in designing scalable, easy-to-maintain applications. They not only makes application development easier, but also offer great flexibility to utilize various ...
- **Integration with Frameworks**: Examples of integrating XDoclet with popular web frameworks like Struts and Spring. #### Chapter 5: XDoclet and Web Frameworks Building on the previous chapter, ...
- **Dynamic Web Applications**: Support for building dynamic web applications using technologies like JSP, Servlets, and frameworks like Spring and Hibernate. #### Part II: Extending Eclipse **...