我编写了一个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.");
}
从这个意义上来说,appConfig
和Bootstrapper
类似超轻量级“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
。
提前致谢!
答案 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。