java ejb3 @PostConstruct

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1108829/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 15:12:46  来源:igfitidea点击:

java ejb3 @PostConstruct

javaejb-3.0

提问by AleIla

I am experimenting with EJB3 on JBoss, developing a stateless bean. Basically once the module has been deployed I need to perform some actions related to load application settings. To do this I've annotated a method as @PostConstruct, which as far as I know from the API instructs the container to invoke it once the bean has been deployed and before get in service. (correct?) Now, I am confused, because from the log on that method looks like is not simply called after has been deployed but before each exposed method is called. I only need to call that method once, not every time it receives a call. What would be the best approach?

我正在 JBoss 上试验 EJB3,开发无状态 bean。基本上,一旦部署了模块,我就需要执行一些与加载应用程序设置相关的操作。为此,我将一个方法注释为@PostConstruct,据我所知,该方法指示容器在部署 bean 后和投入使用之前调用它。(正确吗?)现在,我很困惑,因为从日志上看,该方法看起来不是在部署之后而是在调用每个公开的方法之前简单地调用。我只需要调用该方法一次,而不是每次收到调用时。最好的方法是什么?

Thanks in advance

提前致谢

Alessandro Ilardo

亚历山德罗·伊拉多

采纳答案by Tim H

A stateless bean should be just that - stateless. Meaning that in use, you should neither be able to tell or to care if the bean was pulled from a pool or constructed on demand for your request. I'm hard-put to envision how a PostConstruct could apply to a stateless environment, since I always use that function to finish building a bean's state.

无状态 bean 应该就是这样 - 无状态。这意味着在使用中,您不应该能够分辨或关心 bean 是从池中提取还是根据您的请求按需构建。我很难想象 PostConstruct 如何应用于无状态环境,因为我总是使用该函数来完成构建 bean 的状态。

Apparently, JBoss is either forgoing the pooling of stateless beans and constructing them fresh each time, or, if it is using pooling, treating them like they were reconstructed each time (since they shouldn't be carrying state information). I'm actually a little surprised that it invokes the PostConstruct at all.

显然,JBoss 要么放弃无状态 bean 的池化并每次都以新鲜方式构建它们,或者,如果它使用池化,则将它们视为每次都重新构建(因为它们不应该携带状态信息)。我实际上对它完全调用 PostConstruct 感到有些惊讶。

回答by Mykola Golubyev

First of all PostConstruct is called before first method will be invoked on the bean. If no method will be invoked no post construct ever be called.

首先在 bean 上调用第一个方法之前调用 PostConstruct。如果不会调用任何方法,则不会调用任何 post 构造。

Secondly you can execute inverse actions in PreDestory method to remove side effects.

其次,您可以在 PreDestory 方法中执行反向操作以消除副作用。

Anyway which kind of action you have to perform?

无论如何,您必须执行哪种操作?

回答by Chase

PostConstruct gets called before the client runs a biz method. This means that if the bean isn't pooled the container will instantiate the bean, do injection, call the @PostConstruct method, then allow the biz method to run.

PostConstruct 在客户端运行 biz 方法之前被调用。这意味着如果 bean 没有被池化,容器将实例化 bean,进行注入,调用 @PostConstruct 方法,然后允许 biz 方法运行。

In the case of a pooled be then the @PostConstruct method will be run every time the bean is pulled from the pool. With Stateless beans this will be between every method call. With Stateful beans this will be after client lookup or injection.

在池化的情况下,@PostConstruct 方法将在每次从池中拉出 bean 时运行。对于无状态 bean,这将在每次方法调用之间进行。对于有状态 bean,这将在客户端查找或注入之后进行。

If you need to run something on application deployment your options will depend on the version of Java EE you have.

如果您需要在应用程序部署上运行某些内容,您的选项将取决于您拥有的 Java EE 版本。

For Java EE 6 you can use @Startup on a @Singleton EJB which contains a @PostConstruct method.

对于 Java EE 6,您可以在包含 @PostConstruct 方法的 @Singleton EJB 上使用 @Startup。

For Java EE 5 and previous you'll have to use a ServletContextListener in a web archive. You can have the ServletContextListener call an EJB if you want.

对于 Java EE 5 及更早版本,您必须在 Web 存档中使用 ServletContextListener。如果需要,您可以让 ServletContextListener 调用 EJB。

However what might be a more important question is where do you want to load these application settings to? If you are dealing with a non-clustered single JVM configuration then you probably going to want to load them into a Singleton of some type. In Java EE 5- you'll have to implement the singleton design pattern yourself or in EE 6 use the @Singleton EJB type.

但是,更重要的问题可能是您要将这些应用程序设置加载到何处?如果您正在处理非集群的单个 JVM 配置,那么您可能希望将它们加载到某种类型的单例中。在 Java EE 5 中,您必须自己实现单例设计模式,或者在 EE 6 中使用 @Singleton EJB 类型。

回答by skaffman

It is up to the app server to manage the lifecycle of EJBs. It may decide to construct, initialise and tear down beans whenever it sees fit. It may be that each call to your stateless bean is on a fresh instance of the your bean class, although that does seem like an off thing to do.

由应用服务器来管理 EJB 的生命周期。它可以决定在它认为合适的时候构造、初始化和拆除 bean。可能对无状态 bean 的每次调用都是在 bean 类的一个新实例上进行的,尽管这似乎是一件不合时宜的事情。

Is the app server calling the @PostConstruct method multiple times on the same object instance, or on a different instance each time? Try sticking log statements inside the constructor and the @PostConstruct method.

应用服务器是在同一个对象实例上多次调用@PostConstruct 方法,还是每次在不同的实例上调用?尝试在构造函数和 @PostConstruct 方法中粘贴日志语句。

回答by Damo

How many SLSB do you have in your pool? Depending on the container the @PostConstructmay not be called until the first client accesses it (not sure about JBoss) so this may be why it looks like it is on every access. It would be interesting to see if it stopped calling your post-construct method after calling your method the number of times equalling your pool size.

您的池中有多少 SLSB?根据容器的不同,在@PostConstruct第一个客户端访问它之前可能不会调用它(不确定 JBoss),所以这可能是为什么它看起来像是在每次访问时。看看它是否在调用您的方法的次数等于您的池大小后停止调用您的构建后方法会很有趣。

If you are performing some expensive actions in your post-construct method then maybe do these in a SFSB at startup and "inject" that SFSB into your SLSB in the post-construct.

如果您在后构造方法中执行一些昂贵的操作,那么可能在启动时在 SFSB 中执行这些操作,并在后构造中将该 SFSB“注入”到您的 SLSB 中。