Skip to main content
 首页 » 编程设计

java中在初始化静态变量期间调用 Singleton EJB

2025年12月25日62artech

我有一个线程安全的重资源,我想将其初始化为静态类变量。在初始化该对象期间,我需要从外部属性文件中读取一些“连接”参数。

要读取初始化参数,我想使用令人兴奋的Configuration Singleton EJB,但似乎我注入(inject)的configuration bean在部署时为空(当EE容器初始化时)我的静态变量)。

这是我的配置 EJB:

@Startup 
@Singleton 
@LocalBean 
public class Configuration { 
 
    @Lock(LockType.READ) 
    public String getValue(String key) { 
        return ...; 
    } 
} 

这就是我想要初始化 HeavyObject 的方式:

@Stateless 
public class SenderBean { 
 
    private static HeavyObject something; 
 
    @Inject 
    private Configuration configuration; 
 
    public SendNotificationBean()  { 
        String host = configuration.getValue("...."); 
        String port= configuration.getValue("...."); 
 
        something = new HeavyObject(host, port); 
    } 
} 

但是配置为空:

Caused By: java.lang.NullPointerException 
        at com.aaa.bbb.business.SenderBean.configureProxy(SenderBean.java:187) 

也许我需要更改容器初始化 EJB-s 的顺序?

请您参考如下方法:

它不会工作,因为容器在注入(inject)任何东西之前调用默认构造函数。为此有一个注释@PostConstruct

为了解决这个问题,我还将 HeavyObject 创建为单例 bean,并在其中注入(inject) Configuration。像这样的东西:

@Singleton 
public class HeavyObject { 
 
    @Inject 
    private Configuration conf; 
 
    @PostConstruct 
    private void configure() { 
        // make something with the conf 
    } 
 
} 

并注入(inject)它:

@Stateless 
public class SenderBean { 
 
    @Inject 
    private HeavyObject ho; 
    ... 
} 

当然,这只是一种方法,但我建议避免 bean 中的静态内容,并仔细考虑 bean 的职责是什么。 这就是为什么我将 @PostConstruct 配置逻辑放入 HeavyObject 单例,而不是在 SenderBean 上运行它。

没有什么可以阻止您将 Configuration 注入(inject) SenderBean(如果有用途的话)。