【问题标题】:Is it possible to use CDI interceptor to intercept method invocation from an Entity?是否可以使用 CDI 拦截器来拦截来自实体的方法调用?
【发布时间】:2013-09-10 12:34:34
【问题描述】:

领队想在Entity类里面写一些业务方法,比如:

@Entity
public class SomeProcess extends SomeProcessBase implements Serializable {

    @SomeInterceptor
    public void start() {
        //do some business logics
    }

    @SomeInterceptor
    public void abort() {
        // do some business logics
    }

    ...

}

我们可以使用CDI拦截器机制来拦截非上下文实体对象吗?

【问题讨论】:

  • 您想要使用 CDI 拦截器而不是直接使用 JPA's own interceptors (listeners)@PrePersist@PreUpdate 和朋友的具体原因是什么?为什么不直接在与实体关联的业务服务类中完成 CDI 工作?
  • 感谢 BalusC 的回复。我们正在做基于生命周期验证和通知的转换(它使实体,一个反应对象,从一个状态转换到另一个状态)。
  • 例如,一旦“SomeProcess”实体对象已经处于“started”状态,则不会调用start方法,会发生异常事件让用户或后端服务知道启动请求是非法的。所以Entity的生命周期拦截器是不够的。
  • 好的。那么为什么类是 JPA 实体而不是真正的业务服务呢?
  • 根据核心J2EE模式,有应用服务模式和业务对象(实体或复合实体)模式。而应用服务模式就是解耦不同业务对象之间的依赖关系。业务对象可以实现为实体对象本身或业务服务。我们更喜欢封装,所以我们选择了业务对象,我们认为业务服务打破了实体属性访问的一些封装。业务服务可用于在业务领域内执行逻辑,其范围超出实体对象生命周期本身。

标签: jpa cdi


【解决方案1】:

答案是否定的。

而下一个方向是转移到 BCEL。

经过几天的研究,我终于用BCEL实现了方法拦截。

粗略的解决方案: 1. 使用java instrument 框架在类加载时转换字节码。 Click Reference。 2. 使用bytecode manipulation lib 转换字节码,例如ASM、Javassist 或BCEL。在转换字节码的同时,手动编写目标java文件,并使用这些库提供的一些工具类生成java代码,该java代码可以从目标类文件创建字节码,经过一些封装和装箱和拆箱等,然后转换字节码部分将准备就绪。 BCEL 提供了 BCELifier 类来生成这些 java 代码,bytecode manipulation 还提到了其他库的一些其他工具。 3.尝试github.com上的Lifecycle开源项目,它提供了基于Java的生命周期描述语言,它是一种使用Java描述UML状态机的元驱动风格。而方法拦截请参考BCELClassFileTransformer.java 4. 联系我获取更多帮助。

【讨论】:

  • 你可以包含更多细节:/
猜你喜欢
  • 2011-10-21
  • 2014-03-10
  • 2020-06-17
  • 2012-08-18
  • 2017-01-28
  • 2018-09-04
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
相关资源
最近更新 更多