在EJB jar中,在初始化时只将代码放在哪里执行一次?

时间:2011-11-28 18:38:49

标签: java initialization ejb listener

我需要的是:EJB JAR 中的一个地方来放置从高潜在源(例如来自缓慢连接的DB)读取和缓存配置数据的代码。理想情况下,我希望容器保证此代码只执行一次。

更新:我们使用EJB 3.0,因此@Singleton不是一个选项。 @PostConstruct方法有一个缺点:它们在bean生命周期中执行一次,因此每次创建bean时,都会执行慢速代码。相反,我想在应用程序启动期间只读取一次数据并缓存它。

提供一些上下文:在Java Web应用程序中,我习惯将我的初始化代码放入SessionContextListener.contextInitialized()方法中。 根据Servlet规范JSR 154(部分SRV.9.12,SRV.15.2.12.1),在Web应用程序中的任何过滤器或servlet初始化之前调用此方法,更重要的是,每个给定的侦听器只调用一次。 / p>

我意识到我可以把我的代码放到那个监听器中,但问题是我需要在我的计时器bean中使用那个conifguration数据,这些数据是在会话上下文监听器被触发之前开始的(大概)。我当然可以实现自定义配置工厂,所有这些都被synchronized块削减以处理缓存和并发访问。但手动同步总让我感到恶心。

你们对于在EJB JAR中放置这个“read config”代码有什么想法吗?或者可能是在多线程环境中读取和缓存配置数据的其他方法?

谢谢大家。

3 个答案:

答案 0 :(得分:1)

使用单例EJB。请参阅http://docs.oracle.com/javaee/6/tutorial/doc/gipvi.html

您可以选择急切地或懒洋洋地初始化它。

答案 1 :(得分:0)

您可以将代码放在任何类的static { }块中,每个类加载器只会加载

您可以使用Singleton构造函数和private方法定义static对象,该方法仅返回该类的单个实例。这也属于每个类加载器的一次警告。

请注意,大多数(如果不是所有)J2EE / EJB容器都使用多个类加载器,因此需要对您的特定环境进行大量测试,以保证代码只在您拥有的任何范围内运行一次。

答案 2 :(得分:0)

@PostConstruct下的方法放在 EJB 中,如下所示。

@PostConstruct
public void init()
{
    //Some EJB stuff.
}

加载 EJB 时,方法init()只会执行一次。