Java:自定义DI配置如何适用于WAR和EAR

时间:2012-04-30 16:46:13

标签: java dependency-injection war ear

我编写了一个Bootstrapper类,它从类路径中读取XML文件,并且可以在运行时被其他类用作轻量级依赖注入器:

<!-- myAppConfig.xml -->
<appConfig>
    <environment runningOn="LOCAL" host="localhost.example.com" system="Windows 7"/>
</appConfig>

public class Bootstrapper
{
    private String runningOn = "Unknown";
    private String host = "Unknown";
    private String system = "Unknown";

    public Bootstrapper(final String appConfigFileName)
    {
        setRunningOn(extractRunningOn(appConfigFileName));
        setHost(extractHost(appConfigFileName));
        setSystem(extractSystem(appConfigFileName));
    }

    public String getHost()
    {
        return host;
    }

    // Rest of class ommitted for brevity...
}

// Then in an executable JAR's main method:
public static void main(String[] args)
{
    Bootstrapper bootstrapper = new Bootstrapper("myAppConfig.xml");

    // Prints: "This app is running on the localhost.example.com server node."
    System.out.println("This app is running on the " +
        bootstrapper.getHost() + " server node.");
}

从这个意义上来说,appConfigBootstrapper类似轻量级“DI”机制。

我想知道的是:如何将此设计转换为WAR的web.xml和EAR的server.xml?

在可执行JAR中,main方法显式实例化Bootstrapper,然后可以查询其字段/属性,在WAR / EAR中,所有内容都在XML文件中定义({{ 1}} / web.xml)没有一个“入口点”。所以在WAR或EAR中,如果我有多个类,每个类都需要知道本地主机名是什么,我将不得不一遍又一遍地实例化相同的server.xml,并传递相同的{{1}每一次。

我想知道是否有办法配置web.xml和server.xml以在启动/部署时实例化Bootstrapper,并自动注入/填充我的依赖类当时和那里(或者,至少,将每个依赖类访问赋予XML文件中定义的全局/单例myAppConfig.xml

提前致谢!

1 个答案:

答案 0 :(得分:1)

对于战争(以及因为它将包含战争的耳朵)项目,您可以使用ServletContextListener来实例化您的Bootstrapper。

如何使用ServletContextListener的一个很好的例子是here

但是,如果您使用的是Java EE 6,那么更好的方法是使用EJB 3.1 Singleton和一些CDI。

import javax.ejb.Singleton
import javax.ejb.Startup
import javax.enterprise.context.ApplicationScoped

@Singleton         // EJB 3.1 Singleton
@Startup           // Telling the container to eagerly load on startup
@ApplicationScoped // CDI Scope
public class Bootstrapper {

    private String host = "Unknown";

    @PostConstruct
    public void readConfiguration() {
        // ... load your xml file
    }

    public String getHost() {
        return host;
    }
}

使用上面的内容,您现在可以使用简单的@Inject或@EJB注释在大多数EE 6生态系统中注入此Bootstrapper bean。