Issue Details (XML | Word | Printable)

Key: SPR-4268
Type: New Feature New Feature
Status: Open Open
Priority: Major Major
Assignee: Unassigned
Reporter: David Goblirsch
Votes: 0
Watchers: 0
Operations

If you were logged in you would be able to see more operations.
Spring Framework

Add parameter to ClassPathXmlApplicationContext constructor for configuration

Created: 18/Dec/07 03:10 PM   Updated: 15/Aug/08 02:21 PM
Component/s: SpringCORE
Affects Version/s: None
Fix Version/s: None

Time Tracking:
Not Specified

Environment: JSE instead of JEE


 Description  « Hide
ClassPathXmlApplicationContext will detect PropertyPlaceholderConfigurers that are
configured in the XML file, but these beans point to files.

For those of us using JSE instead of JEE, we often have programs for which some properties
are configured by command line parameters. It would therefore be convenient to be able to
pass a PropertyPlaceholderConfigurer to the ClassPathXmlApplicationContext upon construction
for those properties that change from run-to-run. The main program would

  o parse the command line
  o set up Properties from the command line arguments
  o construct a PropertyPlaceholderConfigurer
  o then create the ClassPathXmlApplicationContext with the configurer as one
    of the constructor parameters.

This way, configuration can be divided into 2 sets of parameters: those configurable by file because they are common
to all the runs of a given application (and thus they can be configured in the config file) and those configurable from the
command line but still allowing the flexibility and non-lazy instantation of beans offered by an ApplicationContext.

Currently, the only way I see to do this is to use a BeanFactory and explicitly post process it. But the ApplicationContext
offers some useful features above and beyond the BeanFactory. That is, it appears that the only way to apply
a PropertyPlaceholderConfigurer to an AppicationContext is to configure it in the XML.



 All   Comments   Work Log   Change History   FishEye   Builds      Sort Order: Ascending order - Click to sort in descending order
Marten Deinum added a comment - 19/Dec/07 03:45 AM
You can pass them as jvm parameters and then those properties will be picked up by the already registered PropertyPlaceHolderConfigurer

java -Dfoo=bar YourProgram

in your configuration refer to ${foo} and it should work.

Next to that (depending on your JRE version) you could pass them to your programm and before instantiating the ApplicationContext call System.setProperty(name, value) to set properties, those will also be picked up by the already configured PropertyPlaceHolder.

David Goblirsch added a comment - 15/Aug/08 02:21 PM
The suggestion works fine for stand alone programs.

Now consider this scenario. Imagine that you have an application for which you need 3 instances,
each running for one of databases A, B, and C. Suppose all are running on the same JBoss
server, which is configured with datasources having JNDI names jdbc/A, jdbc/B, and jdbc/C.
 
Suppose the ApplicationContext is loaded into JBoss using an "ApplicationContext Loader" XMBean,
i.e., custom class that basically extends ServiceMBeanSupport and upon "start()" simply calls ClassPathXmlApplicationContext.
We want to control each system separately, so there is one JBoss "-service.xml" file for each system,
A, B and C. In those service files, one of the custom loader's parameters could be a system id. So in the Application config file you'd like to say

  <jee:jndi-lookup id="dataSource" jndi-name="jdbc/${systemId}" />

and then when A-service.xml loads its Context, it sets systemId to "A", and when B-service.xml loads its Context,
it sets systemId to "B", etc.

Now JBoss uses a shared class loader configuration by default, so unless you go through the
trouble of reducing the application scope, I don't think I can just say System.setProperty( ... )
because these services will share the same classloader and hence the same statics.

Is this not a case where a constructor of the type

   new ClassPathXmlApplicationContext( String[] files, Properties p )

would be useful?