我需要的是: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”代码有什么想法吗?或者可能是在多线程环境中读取和缓存配置数据的其他方法?
谢谢大家。
答案 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()
只会执行一次。