WebSphere 和 PropertyPlaceholderConfigurer
我是属性(使用 PropertyPlaceholderConfigurer)的大用户,以使我的应用程序尽可能“动态”。 几乎所有的常量都是这样定义的。 不管怎样,我目前正在定义一个默认 WAR 附带的 default.properties
。
在其他环境(验收/生产)中,我需要覆盖配置。 我这样做的方式如下:
<bean id="propertyManager"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/company/default.properties</value>
<value>file:${COMPANY_PROPERTIES_LOCATION}\kbo-select-settings.properties</value>
</list>
</property>
</bean>
这意味着我可以为每个环境使用可升级的构建。
然而,我确实不喜欢这样的事实:我无法从 WebSphere 内部更改我的任何属性。 相反,我必须访问每台服务器(我们有 8 个集群)并相应地更改属性。 如果我可以从 WebSphere 内部更改这些内容并在之后执行重新启动,那么用户会更加友好......
任何人都知道我如何进行这样的可推广构建? 我已经为 datasources/java mail/etc 定义了 JNDI 配置。
谢谢!
I'm a big user of properties (with PropertyPlaceholderConfigurer) for making my application as "dynamic" as possible. Almost all the constants are defined as such. Anyway, I'm currently defining a default.properties
which comes shipped with the default WAR.
In other environments (Acceptance/Production) I need to overwrite of the configurations. I'm doing this as following:
<bean id="propertyManager"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/company/default.properties</value>
<value>file:${COMPANY_PROPERTIES_LOCATION}\kbo-select-settings.properties</value>
</list>
</property>
</bean>
With this means I can use a promotable build for each of the environments.
HOWEVER, I do dislike the fact that I can't change any of my properties from inside WebSphere. Instead I have to go to each of the servers (we have 8 clustered) and change the properties accordingly. It would be a lot more user friendly if I could change those from inside WebSphere and just perform a restart afterwards...
Anyone has an idea on how I could do such a promotable build? I already define JNDI configuration for datasources/java mail/etc.
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我们通过在每个环境(local、dev、int、tst ...)的属性文件上使用扩展来解决这个问题,并且每个文件都包含这些环境的特定值。 您需要的唯一添加是服务器上的 VM 参数来设置 -Druntime.env=X。
然后,您在配置文件中的查找将如下所示
当然,这仅在您具有相当静态的环境时才有效,因为它仍然不适合在运行时更改它,但它确实使应用程序的升级变得非常简单。 如果您希望能够在不重新部署应用程序的情况下更改这些值,则必须将它们存储在应用程序外部,您似乎已经在为 kbo-select-settings.properties 执行此操作
We solved this problem by using an extension on the property file for each environment (local, dev, int, tst ...) and each file contained specific values for those environments. The only addition you then require is a VM argument on the server to set -Druntime.env=X.
Your lookups in your config file will then look like this
Of course this only works if you have fairly static environments, as it still doesn't lend itself to changing it at runtime, but it does makes promotion of the application dead simple. If you want to be able to change the values without redeploying your application, you will have to have them stored outside your application, which you already seem to be doing for the kbo-select-settings.properties
一个潜在的问题是您正在对属性文件的位置进行硬编码。 您可以将属性文件的位置指定为 JNDI 资源,并使用类路径上指定的默认值:
这样您就可以使用资源 > 中的 WAS 控制台为不同的环境指定不同的文件名。 网址> 通过使用 JNDI 名称“url/config”创建资源并将其指向正确的文件 (file:///your/path/to/properties) 来获取 URL。
作为替代解决方案,如果您想通过控制台管理各个属性,您可以使用 jee:jndi-lookup 从 web.xml env-entries 获取值(您可以使用 WAS 控制台进行管理),而不是使用 PropertyPlaceholderConfigurer )。 请参阅此答案
One potential issue is that you are hardcoding the location of your properties file. You could specify the location of the properties file as a JNDI resource and falling back on the defaults specified on the classpath:
That way you can specify different file names for different environments using the WAS console in Resources > URL > URLs by creating a resource with the JNDI-name "url/config" and pointing it to the correct file (file:///your/path/to/properties).
As an alternative solution, if you want to manage individual properties through the console, you instead of using the PropertyPlaceholderConfigurer you could use jee:jndi-lookup to get values from the web.xml env-entries (which you can manage using the WAS console). See this answer
如果配置位于 EAR 文件中,那么我知道没有简单的方法可以在没有后门作弊或重新部署应用程序的情况下传播更改。
我认为该配置,尤其是在推广应用程序时更改的配置不应该在应用程序中。
Keys Botzum 在此处描述了一种方法,
请注意,您实际上可以使用标准 WebSphere 同步将不属于任何特定应用程序的文件传播到节点。
另一种选择是使用数据库进行配置。 如今,将 XML 放入 DB(例如 DB2)中并不困难。
If the configuration is in the EAR file then I know of no simple way to propogate changes without backdoor cheats or re-deploying the app.
I think that configuration, espcially that which changes when you promote the app should not be in the application.
One approach is described here by Keys Botzum,
Note that you can actually propogate files that are not part of any particular application out to nodes using standard WebSphere synchronisation.
Another option is to use a database for config. These days poppin XML into a DB such as DB2 is not very hard.
将指向您的配置文件的 URL 资源添加到您的 websphere 服务器,然后在您的应用程序中查找该资源是一种可行的方法。 然后,您可以配置 url 以指向管理所有配置文件的中心位置 - 如果您使用 svn 并且您的 svn 具有只读访问权限,您甚至可以直接从 svn 读取它们(通过 http)。
Spring 为此提供了一些内置工具,这也意味着您可以优先考虑各种配置文件。
有关更多信息,请查看 如何区分应用程序中的测试属性和生产属性
Adding a URL resource that points to your config files to your websphere servers and then looking that up in your application is a viable way to go. You can then configure the url to point to a central location where all the configuration files are managed - if you use svn and your svn has read-only access you could even directly read them from svn (via http).
Spring has some built in facilities for this, and it also means you can priorities various config files.
For more information take a look at how-to-differentiate-between-test-and-production-properties-in-an-application
我处理这个问题的方法是使用 JVM 上的属性值,然后将它们引用到在集群或单元级别定义的 WebSphere 变量。 例如,假设您希望在 spring 配置中的 param1 中设置一个名为 value1 的值,您将执行以下操作:
然后像下面这样引用该变量:
然后在您的测试中,您可以按如下方式设置测试:
然后从websphere 配置中,如果您创建一个 JVM 变量并将其链接到 WebSphere 变量,您只需要更改 WebSphere 变量,它就会自动更新每台机器上的所有 JVM 变量。
为此,创建一个名为:
param1
且值为 ${webspherevar.param1} 的
JVM 变量,然后创建一个名为:
webspherevar.param1
的 WebSphere 变量,其中包含您需要放入其中的任何值。 这使您不必为每个环境传递值,而是可以将它们加载到环境中并直接使用。
我希望这有帮助。
The way that I have dealt with this is to use property values on the JVM's but then reference them to a WebSphere variable that is defined at the cluser or cell level. For example, say you want a value called value1 set in param1 in your spring configuration you would do the following:
And then something like as follows do reference the variable:
Then within your tests you can setup your tests as follows:
Then from within the websphere configuration, if you create a JVM variable and link it to the WebSphere variable you only need to change the WebSphere variable and it will automatically update all the JVM variables on each machine.
To do this, create a JVM variable called:
param1
with a value of ${webspherevar.param1}
And then create a WebSphere variable called:
webspherevar.param1
That contains whatever the value you need to put in it. This allows you to then not have to ship around the values for each environment and they can be instead loaded into the environment and just used.
I hope this helps.