该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2008-05-17
pig345 写道 看来相同技术条件(限制)下,路子都有点相似。
07年中的一个小项目,用的也是类似的法子,DomainObject中的EntityManager是static的,配置Spring注入,只不过还是没有DAO,而只有JPA。 研究Spring配置,还真费了不少功夫(工厂套工厂,代理叠代理的,很容易晕,当时搞明白了,现在可是全忘了),不过后来各方面原因(非技术的),改ROR了。 呵呵Dao还是JPA本质上都差不多,Dao再把JPA封装了一层而已,这样和目前传统的编程方式区别不大,更容易被一些保守党接受。 |
|
返回顶楼 | |
发表时间:2008-05-17
partech 写道 Feiing 写道 inject dao to domain object, 不也是一种 rich domain object 的实现吗 ?
我前面的Finder就对应DAO啊,因为往数据库里持久的任务我们已经采用另一个Aspect集中处理了,所以这里DAO就退化为往外拿Domain对象的Finder了。 public aspect FinderInitialization { private pointcut getXXXFinder() : get(public static * IDomainObject+.*Finder); Object around() : getXXXFinder(){ Object finder = proceed(); if(finder == null) { //注入 ... finder = proceed(); } assert finder != null : thisJoinPoint.getSignature().toShortString() + " 返回 null "; return finder; } } public Employee implements IDomainObject{ public static employeeFinder; ... } //当如下调用时,employeeFinder将被方面自动注入 Employee.employeeFinder.findbyCode(employeeCode); } 我也尝试过Dao退化成finder,但是发现有些批量delete和update的逻辑没处可写-_-! studentFinder.deleteByName("张三"); 这样的代码总觉得很怪,语义有些混乱,就干脆还叫Dao了,其里面也就是find和update的逻辑。 |
|
返回顶楼 | |
发表时间:2008-05-19
Norther 写道 jianfeng008cn 写道 Norther 写道 jianfeng008cn 写道 Norther 写道 谢谢楼上同学的纠正,这个当然算静态property注入,但是,在bean的初始化的时候,每个bean初始化的时间是不确定的,仅spring管理的bean有依赖初始化的关系,而我们的domain model是class级别的注入,这个依赖关系,spring无法知道,而只有在这个MethodInvokingFactoryBean被spring初始化的时候才去注入,有可能这个时候,其他调用Domain Object的quartz的job已经再开始跑了,但是他们去执行一些domain object的方法时,他们都还没有被注入,所以必须要要在所有的bean初始化之前去注入,才能保证所有的spring管理的bean去调用domain object时,他们都是被注入过的。
既然你的调用是有依赖的 用spring配置了这些有依赖关系的bean 那么初始化的时候也肯定会根据这个关系生成实例,怎么会和你说的这样呢? 比方说 a 依赖于b 在实例化a的时候 发现b还没有实例化 那肯定会先去实例化b啊,即使lazy了 哪么用的时候肯定要实例化了吧 那肯定了,这是没办法的,用到的那些DAO等于都先初始化了。 在Spring中,你getBean("a"), 他会初始化a,如果a依赖b,spring就会初始化b,很明确。 但是这种情况下,你初始化一个quartz的任务,开始跑,他里面没有依赖a,只是他里面操作的领域模型Student,依赖a了,还是static的,Student不是被spring管理的,spring不会知道这个关系,它不会注入,也不会初始化a(如果他是lazy的)。 “只是他里面操作的领域模型Student,依赖a了,还是static的,Student不是被spring管理的” 你的意思是特殊情况(调用Student而不是student bean)还是普遍情况 ,如果是说Student bean 那也没道理不让spring管理啊, 看你这个方案不就是在应用启动的时候,先初始化所有的dao bean(还是归spring管理的吧?),然后在domain(如Student,不归spring管?)的class级别初始化static的dao 。我理解有问题? 你理解的没任何问题,Student是不被spring管理的,而他依赖的Dao是spring管理的。 我表达的不清楚吧 你说是Student不被spring管理, 意思是你调用了静态方法 而不是调用student bean? 如果是这样能否说明下 为什么不调用student bean去调用Student呢? |
|
返回顶楼 | |
发表时间:2008-05-19
jianfeng008cn 写道 Norther 写道 jianfeng008cn 写道 Norther 写道 jianfeng008cn 写道 Norther 写道 谢谢楼上同学的纠正,这个当然算静态property注入,但是,在bean的初始化的时候,每个bean初始化的时间是不确定的,仅spring管理的bean有依赖初始化的关系,而我们的domain model是class级别的注入,这个依赖关系,spring无法知道,而只有在这个MethodInvokingFactoryBean被spring初始化的时候才去注入,有可能这个时候,其他调用Domain Object的quartz的job已经再开始跑了,但是他们去执行一些domain object的方法时,他们都还没有被注入,所以必须要要在所有的bean初始化之前去注入,才能保证所有的spring管理的bean去调用domain object时,他们都是被注入过的。
既然你的调用是有依赖的 用spring配置了这些有依赖关系的bean 那么初始化的时候也肯定会根据这个关系生成实例,怎么会和你说的这样呢? 比方说 a 依赖于b 在实例化a的时候 发现b还没有实例化 那肯定会先去实例化b啊,即使lazy了 哪么用的时候肯定要实例化了吧 那肯定了,这是没办法的,用到的那些DAO等于都先初始化了。 在Spring中,你getBean("a"), 他会初始化a,如果a依赖b,spring就会初始化b,很明确。 但是这种情况下,你初始化一个quartz的任务,开始跑,他里面没有依赖a,只是他里面操作的领域模型Student,依赖a了,还是static的,Student不是被spring管理的,spring不会知道这个关系,它不会注入,也不会初始化a(如果他是lazy的)。 “只是他里面操作的领域模型Student,依赖a了,还是static的,Student不是被spring管理的” 你的意思是特殊情况(调用Student而不是student bean)还是普遍情况 ,如果是说Student bean 那也没道理不让spring管理啊, 看你这个方案不就是在应用启动的时候,先初始化所有的dao bean(还是归spring管理的吧?),然后在domain(如Student,不归spring管?)的class级别初始化static的dao 。我理解有问题? 你理解的没任何问题,Student是不被spring管理的,而他依赖的Dao是spring管理的。 我表达的不清楚吧 你说是Student不被spring管理, 意思是你调用了静态方法 而不是调用student bean? 如果是这样能否说明下 为什么不调用student bean去调用Student呢? 你的应用里student能是spring管理的么?所有的Hibernate的entity怎么可能让spring管理,这些对象都是根据业务逻辑控制生命周期的,就是要不被spring管理的domain object要注入被spring管理的bean。 |
|
返回顶楼 | |
发表时间:2008-05-20
domain直接归spring管也未尝不可吧? 我现在有一些帮助类就是这么做的
ps:的确想不到好的办法来管理,statefull bean很难这样处理。 |
|
返回顶楼 | |
发表时间:2008-05-20
在我看来,这就是静态的hibernate session注入
以前自己防rails的activeRecord就是静态注入一个 hibernatetemplate,操作是挺爽的,但在生产上常 报连接已关闭的问题 后来项目不归我管了,就被人改掉了,还骂我的 程序垃圾。。。 |
|
返回顶楼 | |
发表时间:2008-05-20
liuyifan.com 写道 在我看来,这就是静态的hibernate session注入
以前自己防rails的activeRecord就是静态注入一个 hibernatetemplate,操作是挺爽的,但在生产上常 报连接已关闭的问题 后来项目不归我管了,就被人改掉了,还骂我的 程序垃圾。。。 是不一样的,虽然都是静态,但是dao注入和Hibernate Session注入是两码子事,dao是单例的,无状态的,所以才适合static注入,但是hibernate session不是单例的,是有状态的,就不适合static注入。在一般的web应用中,Hibernate Session的生命周期都是open session per request,这个和static的整个应用只有一个是完全不吻合的。 另外你那个Hibernate Templet链接已关闭的问题,肯定是哪个地方没控制好,和Hibernate Templet无关。 |
|
返回顶楼 | |
发表时间:2008-05-20
Norther 写道 liuyifan.com 写道 在我看来,这就是静态的hibernate session注入
以前自己防rails的activeRecord就是静态注入一个 hibernatetemplate,操作是挺爽的,但在生产上常 报连接已关闭的问题 后来项目不归我管了,就被人改掉了,还骂我的 程序垃圾。。。 是不一样的,虽然都是静态,但是dao注入和Hibernate Session注入是两码子事,dao是单例的,无状态的,所以才适合static注入,但是hibernate session不是单例的,是有状态的,就不适合static注入。在一般的web应用中,Hibernate Session的生命周期都是open session per request,这个和static的整个应用只有一个是完全不吻合的。 另外你那个Hibernate Templet链接已关闭的问题,肯定是哪个地方没控制好,和Hibernate Templet无关。 但是session虽然不是单例,但是针对每个domain都是只有一个也可以说是domain级别的“单例”了 ,session也可以说是无状态的,因为状态都是外部管理的,在web的环境中都是open session per request,状态也不需要业务代码中进行维护,状态对业务逻辑是没有影响的,如果是跑schedule或者别的调用方式,session就要刻意管理好,才不至于影响代码的正常执行,session的状态还是要带来额外的关注,所以说静态注入的关键是注入的东西是无状态的,单例并不是必要条件(假如我只有一个basedao作为通用的,同样适合静态注入),理解对的吧? |
|
返回顶楼 | |
发表时间:2008-05-21
如果是分布式数据访问,远程调用?对象是反序列化生成的,那么这个是否只能在服务端进行静态注入?
|
|
返回顶楼 | |
发表时间:2008-05-21
galaxystar 写道 如果是分布式数据访问,远程调用?对象是反序列化生成的,那么这个是否只能在服务端进行静态注入?
加上transient |
|
返回顶楼 | |