简体   繁体   English

java ejb3 @PostConstruct

[英]java ejb3 @PostConstruct

I am experimenting with EJB3 on JBoss, developing a stateless bean. 我正在JBoss上试验EJB3,开发一个无状态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. 为此,我将一个方法注释为@PostConstruct,据我所知,从API开始,指示容器在部署bean之后和服务之前调用它。 (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? 什么是最好的方法?

Thanks in advance 提前致谢

Alessandro Ilardo 亚历山德罗·伊拉多

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. 这意味着在使用中,您既不能告诉或不关心bean是从池中提取还是根据您的请求构建的。 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. 我很难想象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). 显然,JBoss要么放弃无状态bean的池化,要么每次都将它们重新构建,或者,如果它正在使用池化,那么就像每次重建它们一样对待它们(因为它们不应该携带状态信息)。 I'm actually a little surprised that it invokes the PostConstruct at all. 我实际上有点惊讶它完全调用了PostConstruct。

First of all PostConstruct is called before first method will be invoked on the bean. 首先调用PostConstruct,然后在bean上调用第一个方法。 If no method will be invoked no post construct ever be called. 如果不调用任何方法,则不会调用post构造。

Secondly you can execute inverse actions in PreDestory method to remove side effects. 其次,您可以在PreDestory方法中执行反向操作以消除副作用。

Anyway which kind of action you have to perform? 无论如何你必须采取哪种行动?

It is up to the app server to manage the lifecycle of EJBs. 由app服务器来管理EJB的生命周期。 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. 可能是你对无状态bean的每次调用都在你的bean类的一个新实例上,尽管这看起来像是一件令人讨厌的事情。

Is the app server calling the @PostConstruct method multiple times on the same object instance, or on a different instance each time? app服务器是在同一对象实例上多次调用@PostConstruct方法,还是每次在不同的实例上调用@PostConstruct方法? Try sticking log statements inside the constructor and the @PostConstruct method. 尝试在构造函数和@PostConstruct方法中粘贴日志语句。

How many SLSB do you have in your pool? 你的游泳池有多少SLSB? Depending on the container the @PostConstruct may 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. 根据容器的不同,@ @PostConstruct可能不会被调用,直到第一个客户端访问它(不确定JBoss),所以这可能就是为什么它看起来像是在每次访问时。 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. 有趣的是,在调用您的方法后,它是否停止调用您的post-construct方法的次数等于您的池大小。

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中。

PostConstruct gets called before the client runs a biz method. 在客户端运行biz方法之前调用PostConstruct。 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. 这意味着如果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. 在汇总的情况下,每次从池中提取bean时都会运行@PostConstruct方法。 With Stateless beans this will be between every method call. 使用无状态bean,这将在每个方法调用之间。 With Stateful beans this will be after client lookup or injection. 使用有状态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. 对于Java EE 5和之前的版本,您必须在Web存档中使用ServletContextListener。 You can have the ServletContextListener call an EJB if you want. 如果需要,可以让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. 如果您正在处理非集群的单个JVM配置,那么您可能希望将它们加载到某种类型的Singleton中。 In Java EE 5- you'll have to implement the singleton design pattern yourself or in EE 6 use the @Singleton EJB type. 在Java EE 5-中,您必须自己实现单例设计模式,或者在EE 6中使用@Singleton EJB类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM