Java开发网 |
注册 |
登录 |
帮助 |
搜索 |
排行榜 |
发帖统计
|
您没有登录 |
» Java开发网 » Architecture & Framework
打印话题 寄给朋友 订阅主题 |
作者 | Spring configuration note |
floater
Java Jedi 总版主 发贴: 3233 积分: 421 |
于 2005-10-05 12:06
A simple configuration in Spring is like this:
Now the problem is this setting is likely to change, for instance, on app servers, we normally use an JNDI lookup for a connection pool:
Other possible reasons for changes are: 1. Different environments, like dev, qa, and prod env, they could have different urls/usernames/passwords 2. To work with different vendors, like sybase or oracle for databases, weblogic jms vs tibco jms. Dependency injection helps us not care how the dependencies are created, where they come in the view of the callers. However, we still need to integrate all parties together, including the dependencies. Spring provides several ways to integrate these dependencies: 1. Using alias: This is to use the name attribute of the bean tag to define the alias and use the alias tag to hook them together with the references or use the ref tag to reference them directly. For example, with the above two beans defined, we could do this:
or
and then we could call the alias like this:
So, this approach works well in the context of fixed caller reference("dataSource") and varying dependency names. It works particularly well when we have a group of varying dependencies because we could group all alias together in one place, so that there is less chance we could leave out one of ten changes, say. The downside, however, is that we can have only one choice - either alias simpleDataSource or alias jndiDataSource, so we have to comment out the leftover, this requires the configuration code change in the Spring XML file. Therefore, the most suitable usage for aliases is to hook unchanged dependencies between components, as noted in the blogs of Colin and Alef, Spring team. 2. The second option is to use override feature in Spring - if there are same bean settings in several Spring XML files, the later setting will override the previous setting. For example, suppose we have the above jndiDataSource bean defined in some xml file, application.xml, and the simpleDataSource bean defined in application-test.xml, then during testing. If we change both id to "dataSource", then we could include the test xml file:
The dataSource in the test xml file will override the one in the application.xml. Later on, in the prod deployment, we could simply take the test xml file out. Here, the first file is fixed, while the second file contains the changing portion. This approach works well for testing, but still requires code change(either like in the above when we create the context, or in the web.xml when we specify the contextLocation) when we switch between different environments. Though the required code changes in the two above approaches could be avoid through build by copying different files(The changing portion) to a fixed file, they are still an either-or solution, meaning we can't have both settings built in. 3. While the above two approaches work well to integrate components, it comes a little bit short for external resource settings. Now we are going to add one more level of indirection so that we can have a runtime selection of options. The first approach is to use Spring's PropertyPlaceholderConfigurer class. A simple example is like this:
And the jdbc.properties is like this:
While the reference of the location in the placeholderConfig bean is fixed, we could change it to a varying location:
Now this ${env} can be set through the jvm parameter(e.g., java -Denv=dev ....). So by setting different properties, we could vary different jdbc settings. In order to be able to switch between the simpleDateSource and jndiDataSource in the beginning of this article, we could do this:
and we have two different dataSource files:
and
In this way, we could use a jvm parameter(a runtime parameter) to select which properties file to use, and thus which dataSource to use. Another possible way to add the extra level of indirection is through proxy technics, but I haven't tried it yet. 4. While using a jvm rumtime properties, sometimes we still want to use a file to specify which configuration to use, say we want to have a file like this:
We want to use this to flag what to use. The PropertyPlaceholderConfigurer class is not sufficient for this purpose, it works only for jvm system setting. This is because the locations field in PropertyPlaceholderConfigurer is of Resource[] and other PropertyPlaceholderConfigurer beans don't resolve any ${...} for Resource objects(or it's trying to resolve ${} after the PropertyEditor converts String to Resource). So we create an enclosure for PropertyPlaceholderConfigurer to do this:
and create a pseudo "editor":
All it does is to keep the locations as strings until all dependent PropertyPlaceholderConfigurer objects resolved references and then convert strings to Resources and apply to references. A simple usage is as follows;
The env bean will be loaded first and resolve ${env} in the placeholderConfig bean. The last two approaches can make a selection on options, but through extra properties files. The selection key can be a jvm system parameter during runtime, or a parameter in a file, which could be set during build time or modified during deployment time(or possibly during runtime with a file watchdog and context refresh()). In the above, we summarized 4 different ways to specify configurations. The first two approaches are more suitable for component composition(or COA - component oriented architecture), i.e., integrate components together, rather than considering the options to select, the last two approaches are better for resource settings, i.e., to select among choices. Side notes: Considering gongshi's pointing out: http://www.cjsdn.net/post/view?bid=32&id=158304&sty=1&tpg=1&age=0, I thus have to claim that this article is 100% authenticate homemade bits. If any search through google on the internet has positive result, then it is purely a copycat, . Of course, use it at your own risk, it could be vaporated, .
floater edited on 2005-10-05 12:23
"Any fool can write code that a computer can understand. Good programmers write code that humans can understand." - Martin Fowler, Refactoring - Improving the Design of Existing Code |
作者 | Re:Spring configuration note [Re:floater] |
davidself
猫哥 CJSDN高级会员 发贴: 1506 积分: 333 |
于 2005-10-07 08:08
休假回来就看到好文章,收藏先,上班再看! --108的上铺-- davidself@twitter |
作者 | Re:Spring configuration note [Re:floater] |
down4u
Jute Pro User 发贴: 119 积分: 51 |
于 2005-10-09 17:14
经验!收藏!谢谢floater! |
作者 | Re:Spring configuration note [Re:floater] |
yeafee
javaholder 发贴: 42 积分: 1 |
于 2005-11-03 16:59
好生景仰! |
已读帖子 新的帖子 被删除的帖子 |
Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1 客服电话 18559299278 客服信箱 714923@qq.com 客服QQ 714923 |