在使用POJO组件对象时,常常需要在对象实例化之后,调用该对象的某个初始化方法。例如,
PersistentLayer.init()
我们在持久层里准备一些初始的业务数据,如第一个超级用户和一些数据字典。
在Spring框架中,提供了这种post-constructor的初始化方法调用机制,但Guice却没有。Guice甚至不理会无参构造方法。(两点说明:1. 在构造方法中完成初始业务数据的准备不太妥当,构造方法应该保持简单,尽量不要加入业务逻辑。2. Guice不执行无参数构造方法,我只是简单试了一下,确实如此。Guice的这个feature肯定有自己的考虑,需要读源码确认,并查一些资料,了解背后的设计考虑。)
这个问题困扰了我们半个小时,考虑过两种绕过去的方法。
一是在封装Guice的Factory中,对对象实例进行处理,如果对象有init()方法,就执行一下。这种方法并不漂亮,涉及泛型、反射,有点复杂。
二是在应用代码中每次请求PersistentLayer时,调init()方法,设置一个静态开关变量,记录是否已经初始化过。同样,这种方法不漂亮,涉及了很多重复。将一个隐含的假定(使用PersistentLayer时,必须先调用init()方法)扩散到了应用代码的各个地方,这种重复是不能容忍的。
最后找到了一个解决方案,即使用Guice的“绑定到实例”的能力。在MyModule.class中,
PersistentLayer pl = new PersistentLayerMemImpl();
pl.init();
binder.bind(PersistentLayer .class).toInstance(pl);
网上有人提到“Guice目前来说还只是个玩具”,提出如下问题:
“不可否认Guice是一个设计精巧的IoC容器,速度也很快,但是这个容器连最基本的对象生 命周期管理都没有,也就是要提供JSR-250里面javax.annotation.PostConstruct和PreDestroy的功能,有人提 出用无参数的@Inject方法来模拟init,这样明显是对Annotation的滥用,用构造参数注入然后在构造方法里面做初始化,这虽然是一种解决 方法,但是有的情况下对象可能需要reinitialize,这样还是需要把初始化单独做为一个方法,用finalize方法来做destroy更不可 取,没法控制什么时候执行.这个问题去年三月就有人提出来了到现在还没有解决,Guice的开发者还是不够活跃,这里这么多人捧Guice,不知道有多少人正式用在项目中.”
我想这种方法也许是一种解决方案。
没有评论:
发表评论