| |
| 怎样用spring来重构这样一个遗留系统? |
| |
发布者: 发布时间:2007-07-27 |
|
|
|
我们现在经手的这个系统,有这么一个非常非常核心的类: ImplFactory。它有一个非常非常核心的方法:
代码
- ImplFactory.newClass(Class type, Object[] args);
这个方法什么意思呢?基本上和调用new type(arg1, arg2, ...)差不多。只不过是动态的,类型不安全的。 为什么要这么做呢?其本意是,后面有一个ImplFactory.properties文件,当调用newClass(MyType.class, new Object[]{a,b,c})的时候,ImplFactory会先检查ImplFactory.properties,如果发现MyType有个子类被登记了,就用那个子类,否则就用MyType本身。无论如何,args都会被作为构造函数的参数传入。
有些对newClass()的调用非常复杂冗长。比如系统某些地方要对某个service包裹一层logging支持,那么要先用newClass找到logger instance,然后用newClass找到这个service,最后还要用newClass来把这个logger和service封装到一个LoggedService(或者子类)中。
这个系统的另外一个讨厌的地方是,到处出现的appId和sessionId两个变量。这两个变量根据程序的上下文值会不同。而在调用ImplFactory.newClass的时候50%的情况需要传递这两个变量,很烦琐。
现在,考虑用spring重构。难点为:
1。希望能够暂时不动ImplFactory.properties文件。因为大家(包括客户)已经习惯于用它了。最好能在spring.xml里面写:
代码
- <include properties="ImplFactory.properties"/>
然后额外的一些比较复杂的组装比如logging,用spring xml来搞。 2。希望保留系统原来的缺省类型语义,配置文件可以只用来配置customization。有时候如果newClass(MyClass.class)的这个MyClass不需要提供一个子类,可以直接用new MyClass(),而不是要求必须在spring xml里面配置MyClass。 3。无论spring如何配置,希望允许参数从外部传递进来。newClass(MyClass.class, new Object[]{a,b})希望能够把a和b传递给被spring配置的组建类。 4。appId和sessionId的传递很烦琐,希望能够把它们作为所有组件的全局变量。而不用每次都传递。(这样可以减少多于一半的传递额外参数的需要了)而如果作为全局变量,希望不同上下文的不同值能够被正确反映,而且线程安全,而且不严重影响并发性。
最后,如果这些需求都能做到,我就可以用dynamic proxy,那container实现一个强类型的ServiceFactory,最终客户的调用代码会变成:
代码
- MyClass mc = factory.getMyClass();
- MyService service = factory.getMyService(a, b);
然后再把ServiceFactory注射到使用ImplFactory的类里面来代替它,就算搞定了。
我是暂时还没有发现用spring怎么实现这些需求,用yan倒是可以。正好借着spring讨论的热乎劲儿,请spring的专家给鉴定鉴定。
| 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。若作者同意转载,必须以超链接形式标明文章原始出处和作者。 相关文章: 关于spring 2.0自定义xml 标记 (二 如何实现) 关于spring 2.0自定义xml 标记 (一 主要的相关类)
|
| (转载文章请保留出处:北天JAVA技术网(www.java114.com)) |
| |
| 更多精彩文章: |
| 在Java程序中实现高精度打印 |
| 类Excel报表设计器标准 |
| 一个使用JAVA xmlencoder 例子 |
| 探讨Java与Ruby语言迁移时的安全性 |
| 用纯JAVA语言编程读取MAC地址的实现 |
| 用AJAX编写用户注册时的应用实例 |
| |
| 最近评论: |
|
|
| 你曾悄悄的来过! |
| wow gold,wow gold,wow gold,ffxi gil max(2466) |
|
|
| 冰封的往事! |
| wow power leveling,wow gold,wow power leveling,wow gold
max(5737) |
|
|
| 冰封的往事! |
| wow power leveling,wow gold,WoW Gold,wow gold
max(6803) |
|
|
| 冰封的往事! |
| wow power leveling,wow gold,WoW Gold,wow gold
max(1585) |
|
|
| 冰封的往事! |
| wow power leveling,wow gold,WoW Gold,wow gold
max(7566) |
|
|
| 冰封的往事! |
| wow power leveling,wow gold,WoW Gold,wow gold
max(5691) |
|
|
| 飞舞的传奇! |
| 传世私服,传世私服.传奇世界私服传奇世界私服,传世私服传世私服, 传奇世界私服传奇世界私服.传奇私服传奇私服. max(5983) |
|
|
| |
| 免责声明:该文章由网友发表,如果对您造成侵权,请联系站长。 |
|
我们也正想大规模重构系统
把ejb从系统中踢出去
但是一点头絮都没有
如果可能把你的过程写成blog好不好
PS:可不可以加我为好友
1,2,3这么理解?
调用: ImplFactory.newClass(Class type, new Object[]{a,b});
ImplFactory.properties里面有
MyType=DefaultMyTypeImpl.class
spring.xml里(这个配置是随手写的):
<bean id="任意" class="DefaultMyTypeImpl">
<constructor-arg index="0">${0}</constructor-art>
<constructor-arg index="1">${1}</constructor-art>
<constructor-arg index="2">
<ref bean="其它spring组件"/>
</constructor-art>
</bean>
这些组件要注入其它bean吗?
1,2,3这么理解?
调用: ImplFactory.newClass(Class type, new Object[]{a,b});
ImplFactory.properties里面有
MyType=DefaultMyTypeImpl.class
spring.xml里(这个配置是随手写的):
<bean id="任意" class="DefaultMyTypeImpl">
<constructor-arg index="0">${0}</constructor-art>
<constructor-arg index="1">${1}</constructor-art>
<constructor-arg index="2">
<ref bean="其它spring组件"/>
</constructor-art>
</bean>
这些组件要注入其它bean吗?
比如调用newClass(com.mycom.MyType.class, new Object[]{a,b})的时候,如果properties文件没有对com.mycom.MyType登记,那么直接调用new MyType(a,b);
而如果有,比如:
com.mycom.MyType=com.mycom.MySubType
那么就new com.mycom.MySubType(a,b)
最终当这个properties文件不用了,或者我们选择在appcontext.xml中配置比较复杂的组件,比如你的例子中的那个,希望客户接口不变。还有,如果这个DefaultMyTypeImpl需要用appId,希望能这么写(或者等价的方法)
这个组件有可能注入其它bean的,至少我们不希望被剥夺这个可能性。
哦,明白了,要学习一番spring才知道,现在只知道从ApplicationContext下手,但里面那套复杂的wire,parent,child context不知道是怎样的。
说明一下,
1不是必要的。如果不好弄,大不了我自己写代码读这个property文件然后自己登记appcontext。关键是2,3,4。如果做不到,spring就只能被枪毙了。
关于3,柞一想似乎不合理。难道要求所有的子类都必须接受a,b两个参数?可仔细一想,存在的就有其合理性。也许不是所有的实现都必然需要接受这两个参数,但是至少典型的实现都要这两个参数。
我用yan实现这个功能的时候,如果配置的实现类不需要这两个参数,也没关系,程序会自动忽略传进来的参数。
从spring的BeanFactory接口来看,目前似乎做不到。它只有getBean(beanName),而没有办法额外传递参数。
所以目前我只实现了yan的prototype,spring和pico都还没着落呢。
自己扩展一个spring的BeanFactory类,在afterpropertyset方法里添加自己想要的参数咯!
有点怀疑你自己都不知道自己在说什么。
afterpropertiesset是对象已经创建了之后才调用的,怎么可能处理构造函数的参数?
扩展BeanFactory又能和afterpropertieset扯上什么联系?
有点怀疑你自己都不知道自己在说什么。
afterpropertiesset是对象已经创建了之后才调用的,怎么可能处理构造函数的参数?
扩展BeanFactory又能和afterpropertieset扯上什么联系?
写一个spring的FactoryBean,在配置文件里可以随意配置你需要的参数,在这个factorybean中再去创建你实际需要的对象,这只不过是可以实现从配置文件里读取属性而已。
所以目前我只实现了yan的prototype,spring和pico都还没着落呢
我的思路是这样的,实现一个称为
ThreadSafeApplicationContext的context
ImplFactory的实现是这样的:
context.register( type,args );
context.register( "sessionId",sessionId );
return context.getBean(type);
另外:spring再怎么整也比不了yan的设计啊...哈哈。
所以目前我只实现了yan的prototype,spring和pico都还没着落呢
我的思路是这样的,实现一个称为
ThreadSafeApplicationContext的context
ImplFactory的实现是这样的:
context.register( type,args );
context.register( "sessionId",sessionId );
return context.getBean(type);
另外:spring再怎么整也比不了yan的设计啊...哈哈。
能不能具体解释一下,这个args是怎么用到每个bean上去的?
我们现在经手的这个系统,有这么一个非常非常核心的类:
ImplFactory。它有一个非常非常核心的方法:
这个方法什么意思呢?基本上和调用new type(arg1, arg2, ...)差不多。只不过是动态的,类型不安全的。
为什么要这么做呢?其本意是,后面有一个ImplFactory.properties文件,当调用newClass(MyType.class, new Object[]{a,b,c})的时候,ImplFactory会先检查ImplFactory.properties,如果发现MyType有个子类被登记了,就用那个子类,否则就用MyType本身。无论如何,args都会被作为构造函数的参数传入。
有些对newClass()的调用非常复杂冗长。比如系统某些地方要对某个service包裹一层logging支持,那么要先用newClass找到logger instance,然后用newClass找到这个service,最后还要用newClass来把这个logger和service封装到一个LoggedService(或者子类)中。
这个系统的另外一个讨厌的地方是,到处出现的appId和sessionId两个变量。这两个变量根据程序的上下文值会不同。而在调用ImplFactory.newClass的时候50%的情况需要传递这两个变量,很烦琐。
现在,考虑用spring重构。难点为:
1。希望能够暂时不动ImplFactory.properties文件。因为大家(包括客户)已经习惯于用它了。最好能在spring.xml里面写:
代码
- <include properties="ImplFactory.properties"/>
然后额外的一些比较复杂的组装比如logging,用spring xml来搞。
2。希望保留系统原来的缺省类型语义,配置文件可以只用来配置customization。有时候如果newClass(MyClass.class)的这个MyClass不需要提供一个子类,可以直接用new MyClass(),而不是要求必须在spring xml里面配置MyClass。
3。无论spring如何配置,希望允许参数从外部传递进来。newClass(MyClass.class, new Object[]{a,b})希望能够把a和b传递给被spring配置的组建类。
4。appId和sessionId的传递很烦琐,希望能够把它们作为所有组件的全局变量。而不用每次都传递。(这样可以减少多于一半的传递额外参数的需要了)而如果作为全局变量,希望不同上下文的不同值能够被正确反映,而且线程安全,而且不严重影响并发性。
最后,如果这些需求都能做到,我就可以用dynamic proxy,那container实现一个强类型的ServiceFactory,最终客户的调用代码会变成:
然后再把ServiceFactory注射到使用ImplFactory的类里面来代替它,就算搞定了。
我是暂时还没有发现用spring怎么实现这些需求,用yan倒是可以。正好借着spring讨论的热乎劲儿,请spring的专家给鉴定鉴定。