我正在使用 Spring 处理对某些远程服务器的 RMI 调用。 构建应用程序上下文并从客户端内部获取用于远程调用的 bean 非常简单:
ApplicationContext context = new ApplicationContext("classpath:context.xml");
MyService myService = (MyService ) context.getBean( "myService " );
但是我没有看到将属性传递到配置中的简单方法。 例如,如果我想在客户端运行时确定远程服务器的主机名。
理想情况下,我希望在 Spring 上下文中有一个像这样的条目:
<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>
并将属性作为参数从客户端传递到上下文。
我可以在上下文中使用 PropertyPlaceholderConfigurer 来替换这些属性,但据我所知,这只适用于从文件读取的属性。
我有一个解决这个问题的实现(作为答案添加),但我正在寻找一个标准的 Spring 实现以避免滚动我自己的实现。 是否有另一个 Spring 配置器(或其他任何东西)来帮助初始化配置,或者我最好查看 java 配置来实现此目的?
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?
发布评论
评论(5)
请参阅http://forum.springsource.org/showthread.php?t=71815
See http://forum.springsource.org/showthread.php?t=71815
我现有的解决方案涉及定义一个新的 MapAwareApplicationContext ,它将 Map 作为附加的构造函数参数。
它重写 postProcessBeanFactory() 以添加 MapAwareProcessor:
MapAwareProcessor 实现 postProcessBeforeInitialization() 以将地图注入到实现 MapAware 接口的任何类型中:
然后我将一个新 bean 添加到我的配置中以声明 MapAwarePropertyPlaceholderConfigurer:
配置程序实现 MapAware,因此它将被注入上面的地图。 然后它实现resolvePlaceholder()来解析地图中的属性,或委托给父配置器:
My existing solution involves defining a new MapAwareApplicationContext that takes a Map as an additional constructor argument.
It overrides postProcessBeanFactory() to add in a MapAwareProcessor:
The MapAwareProcessor implements postProcessBeforeInitialization() to inject the map into any type that implements the MapAware interface:
I then add a new bean to my config to declare a MapAwarePropertyPlaceholderConfigurer:
The configurer implements MapAware, so it will be injected with the Map as above. It then implements resolvePlaceholder() to resolve properties from the map, or delegate to the parent configurer:
更新:
根据问题更新,我的建议是:
ServiceResolver
bean,它根据客户端输入处理您需要处理的任何内容;然后,
ServiceResolver
可以在init-method
上或在每次调用时基于 JNDI 查找或环境变量等确定返回给客户端的值。但在此之前,您可能需要查看
如果您需要从自定义位置查找属性,请查看 org.springframework.beans.factory.config.BeanFactoryPostProcessor 以及 org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 如何使用 已实现。
基本思想是,您获取具有“原始”属性的 bean,例如
${jdbcDriverClassName}
,然后您可以解析它们并将它们替换为所需的值。Update:
Based on the question update, my suggestion is:
ServiceResolver
bean which handles whatever you need to handle based on client input;The
ServiceResolver
can then, either on theinit-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:
If you need to lookup properties from a custom location, take a look at
org.springframework.beans.factory.config.BeanFactoryPostProcessor
and how theorg.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.PropertyPlaceholderConfigurer 可以从文件中获取属性,这是事实,但如果找不到它们,它就会转而使用系统属性。 这听起来像是您的客户端应用程序的一个可行选项,只需在启动客户端时使用 -D 传递系统属性即可。
来自 javadoc< /a>
PropertyPlaceholderConfigurer can fetch properties from a file, that's true, but if it can't find them, it falls back to using system properties. This sounds like a viable option for your client application, just pass the system property in using -D when you launch the client.
From the javadoc
创建一个
RmiProxyFactoryBean
实例并直接在代码中配置serviceUrl
属性:Create an
RmiProxyFactoryBean
instance and configure theserviceUrl
property directly in your code: