Java 在EJBJAR中,在哪里放置只在初始化时执行一次的代码?

Java 在EJBJAR中,在哪里放置只在初始化时执行一次的代码?,java,initialization,ejb,listener,Java,Initialization,Ejb,Listener,我需要的是:EJBJAR中的一个地方,用于放置从高度潜在的源(例如,从连接缓慢的数据库)读取和缓存配置数据的代码。理想情况下,我希望容器能够保证此代码只执行一次 更新:我们使用EJB3.0,所以@Singleton不是一个选项@PostConstruct方法有一个缺点:它们在bean生命周期中执行一次,所以每次创建bean时,我们的代码都会执行得很慢。相反,我希望在应用程序启动期间只读取一次数据并缓存它 给出一些上下文:在Java Web应用程序中,我习惯于将初始化代码放入SessionCont

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

更新:我们使用EJB3.0,所以
@Singleton
不是一个选项
@PostConstruct
方法有一个缺点:它们在bean生命周期中执行一次,所以每次创建bean时,我们的代码都会执行得很慢。相反,我希望在应用程序启动期间只读取一次数据并缓存它

给出一些上下文:在Java Web应用程序中,我习惯于将初始化代码放入
SessionContextListener.contextInitialized()
方法中。 根据Servlet规范(第SRV.9.12节、第SRV.15.2.12.1节),在初始化web应用程序中的任何筛选器或Servlet之前调用此方法,更重要的是,每个给定侦听器只调用一次

我意识到我可以将代码放入该侦听器中,但问题是我需要在启动会话上下文侦听器之前启动的计时器bean中的conifguration数据。当然,我可以实现自定义配置工厂,所有配置工厂都被
synchronized
块砍掉,以处理缓存和并发访问。但是手动同步总是让我恶心

你们对在EJBJAR中把这个“read-config”代码放在哪里有什么想法吗?或者在多线程环境中读取和缓存配置数据的其他方法


谢谢大家。

您可以将代码放入任何类的
静态{}
块中,每个类加载器只加载一次

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

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

使用单例EJB。看


您可以选择立即或延迟地初始化它。

EJB中的
@PostConstruct
下放置一个方法,如下所示

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


方法
init()
仅在加载EJB时执行一次。

静态块不能引用非静态成员。这是一个不应该出现在EJB中的限制。@Lion,我从来没有说过应该这样做,在我的回答中也没有任何暗示。是的,这是我倾向于的-我看到的唯一的缺点是静态初始值设定项中抛出的异常会导致ExceptionInInitializerError和(AFAIR)后续的NoClassDefFoundError在捕获块中看起来很难看。谢谢!不幸的是,我们使用EJB3.0,其中缺少单例bean。谢谢!但是这个方法将对每个新的bean实例执行——我希望对所有bean只执行一次。