jakarta-ee - @PreDestroy 是否在 JavaEE 6 中的 @PostConstruct 异常后被调用?

标签 jakarta-ee jboss ejb java-ee-6 cdi

目前,我们在 JavaEE 6 的 @PostConstruct 方法中遇到了一个更复杂的初始化问题。有几个地方可能会出错,并且可能会出现异常。在那种情况下,我们可能有一个半初始化的 bean。

在这种情况下是否调用了@PreDestroy 方法?我们可以在那里检查我们的资源,并在必要时释放它们。或者我们是否需要捕获 @PostConstruct 中的所有异常并清除那里的所有内容?规范对此并不清楚(或者我没有找到)。

或者,由于缺乏规范,它是否特定于供应商?在 JBoss 7.x 上怎么样?

最佳答案

我认为 EJB3.1 规范在这种情况下很明确:如果您在 PostConstruct 中获取了非托管资源,那么您必须自己释放它们以防出现异常。

第 14.3.3 节 - session Bean 的 PostConstruct 和 PreDestroy 方法的异常 容器操作:记录异常或错误。 如果是单例,则回滚任何容器启动的事务。 丢弃实例。

第 14.3.11 节 - 资源发布 当容器因为系统异常而丢弃实例时,容器应该释放实例持有的所有资源,这些资源是通过在企业 bean 环境中声明的资源工厂获取的(参见 16.7 小节)。

注意:虽然容器应该释放实例通过在企业 bean 环境中声明的资源工厂获取的与资源管理器的连接,但通常情况下,容器不能释放实例可能通过其获取的“非托管”资源JDK API。例如,如果实例打开了 TCP/IP 连接,大多数容器实现将无法释放连接。连接最终会被JVM垃圾回收机制释放。

以下两节指定在 EJB 业务方法或@PostContruct 中发生 RuntimeException 时不调用 @PreDestroy 方法:

4.7.3处理异常 企业 bean 类的任何方法(包括业务方法和容器调用的生命周期回调拦截器方法)抛出的不是应用程序异常的 RuntimeException 导致转换到“不存在”状态。异常处理在第 14 章中有详细描述。有关生命周期回调拦截器方法的规则,请参阅第 12.5.1 节,当多个此类方法应用于 bean 类时。 从客户端的角度来看, session 对象继续存在。客户端可以继续访问 session 对象,因为容器可以将客户端的请求委托(delegate)给另一个实例。

12.5.1异常 生命周期回调拦截器方法可能会抛出系统运行时异常,但不会抛出应用程序异常。 任何生命周期拦截器回调方法抛出的运行时异常都会导致 bean 实例及其拦截器在拦截器链展开后被丢弃[59]。 当 bean 和拦截器因此类异常而被丢弃时,不会调用 PreDestroy 回调:链中的生命周期回调拦截器方法应在拦截器链展开时执行任何必要的清理操作。

关于jakarta-ee - @PreDestroy 是否在 JavaEE 6 中的 @PostConstruct 异常后被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14599421/

相关文章:

Java EE 如何在启动时运行类

java - 如何在仅使用 HTML5 的 J2EE 项目中使用 EL(表达式语言)

multithreading - 在单例 session Bean 中管理并发访问

java - 家庭/远程接口(interface) EJB 3.1 的目的是什么

java - Google App Engine 的响应编码(不能改变响应编码)

java - 在具有多个数据源的 JBOSS 上部署应用程序时出现问题

jboss - Maven 错误 - 每次都下载依赖项

java - 如何在intellij中使用gradle运行arquillian test,如何设置build.gradle文件?

java - 从 jboss 5 迁移到 7

java - 访问安全域时出现 EJBAccessException