Search code examples
javaspringrmi

Passing properties to a Spring context


I'm using Spring to handle RMI calls to some remote server. It is straightforward to construct an application context and obtain the bean for remote invocations from within the client:

ApplicationContext context = new ApplicationContext("classpath:context.xml");

MyService myService = (MyService ) context.getBean( "myService " );

However I don't see a simple way to pass properties into the configuration. For example if I want to determine the host name for the remote server at runtime within the client.

I'd ideally have an entry in the Spring context like this:

<bean id="myService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
  <property name="serviceUrl" value="rmi://${webServer.host}:80/MyService"/>
  <property name="serviceInterface" value="com.foo.MyService"/>
</bean>

and pass the properties to the context from the client as a parameter.

I can use a PropertyPlaceholderConfigurer in the context to substitute for these properties, but as far as I can tell this only works for properties read from a file.

I have an implementation that addresses this (added as an answer) but I'm looking for a standard Spring implementation to avoid rolling my own. Is there another Spring configurer (or anything else) to help initialise the configuration or am I better off looking at java config to achieve this?


Solution

  • Update:

    Based on the question update, my suggestion is:

    1. Create a ServiceResolver bean which handles whatever you need to handle based on client input;
    2. Declare this bean as a dependency to the relevant services;
    3. At runtime, you may update / use this bean however you see fit.

    The ServiceResolver can then, either on the init-method or on each invocation determine the values to return to the client, based on e.g. JNDI lookups or enviroment variables.

    But before doing that, you might want to take a look at the configuration options available. You can either:

    • add property files which don't have to be present at compile-time;
    • look up values from JNDI;
    • get values from the System.properties.

    If you need to lookup properties from a custom location, take a look at org.springframework.beans.factory.config.BeanFactoryPostProcessor and how the org.springframework.beans.factory.config.PropertyPlaceholderConfigurer is implemented.

    The basic idea is that you get the beans with the 'raw' properties, e.g. ${jdbcDriverClassName} and then you get to resolve them and replace them with the desired values.