我继承了一个Struts2项目,该项目需要添加一些功能。当我碰到代码来猜测前一个家伙的工作方式时,我发现如果他想让一个类仅在Tomcat服务器启动时实例化一次(因为它必须从磁盘读取大量数据,而对于例如,获取其配置),他可以通过以下方式做到这一点:
public class ExampleClass {
public ExampleClass(){//Read files and stuff to initialize}
public Object method(Object[] args){//The job to do}
}
然后,在使用它的struts动作中,他以这种方式实例化:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass()
public String execute() {
//Do stuff every time the action is called
Object result = example.method(args);
// Do stuff with results
}
}
我从servlet时代就知道这可以解决问题,但是,我觉得以前处理过这个问题的人和我一样在Struts2中是没有经验的,所以这是我的问题:
这是根据样式建议和最佳实践的正确方法吗? struts2是否提供了一种更受控的方法?
我在这里找到了一些与简单参数有关的答案,但是我不确定这是否是类似对象的正确方法?如果ExampleClass实例非常繁重,会发生什么?我不希望它们被复制:
How to set a value in application scope in struts2?
有关ExampleClass的背景:调用构造函数时,它将读取大量文件并从中提取其配置,从而创建复杂的内部表示形式。 调用method()时,它将使用规则分析其参数,并将结果输出给用户。此过程通常需要几秒钟,并且不会修改以前初始化的规则值。
它正在Tomcat 7中运行,但是,我计划在一切就绪后升级到Tomcat 8.5。我想知道是否与此设置相关的已知问题(代码中没有其他不兼容性)。
顺便说一句:他没有检查ExampleClass是否损坏或类似的东西,这绝对像是灾难xD的配方。实际上,如果我删除源文件,它仍在尝试执行method()...可怜的灵魂...
理想情况下,我需要一种方法来在启动时实例化我所有的应用程序级对象(它们是应用程序本身,其余的只是一个接口),以使Struts2能够知道Tomcat不会发动那场战争,并带有相应的错误日志记录等等。
如果Struts2不支持此功能,这是公认的解决方法?也许某些拦截器可以检查对象状态并返回错误页面(如果尚未正确实例化)?从内部执行部分tomcat?
该项目的所有对象都是线程安全的(它们内部唯一的写操作是在初始化时执行的),但是我想知道当对象不是那么简单时Struts2的最佳实践。如果用户实际上可以破坏一个,该怎么办? (我知道我应该以任何方式避免这种情况发生,但是确实发生了错误,因此我需要一种安全的方法来通过它们并得到适当的警报,当然,我需要一种可以安全地重新实例化或停止故障的方法。整个服务)。
现在,我可以手动执行以下操作:
public class SomeAction extends ActionSupport {
ExampleClass example = new ExampleClass();
private boolean otherIsBuildingExample = false;
public String execute() {
if(otherIsBuildingExample) return '500 error';
if(example==null || example.isBroken()){
otherIsBuildingExample = true;
example = new ExampleClass();
otherIsBuildingExample = false;
}
Object result = example.method(args);
// Do stuff with results
}
}
的确,使用Interceptor可以使它更干净,但是,这听起来像是在并发性***中感到痛苦,特别是考虑到这种示例需要花费几秒钟的时间来开始,并且可能还会有更多请求,因此还有更多需要考虑的问题,例如:如果两个人调用if(otherIsBuildingExample),而第二个人在第一个执行otherIsBuildingExample = true之前获得值,该怎么办?没有什么好...如果该类足够简单,则两者都将实例化,并且较慢的一个将占优势,但是如果一个实例化阻塞了另一方的资源...那么,更多的问题。
我能想到的唯一干净的解决方案是使ExampleClass具有足够的鲁棒性,以便您可以使用其自己的方法(而不是重新实例化)重新使用它,并以通用的方式使这些线程安全(如果有10个人尝试修复它,则只有一个会继续,例如其他人只是在等待第一个结束继续。
或者也许每次您调用execute()时,您都会得到示例的副本,所以对此完全不用担心吗?
我正在研究struts文档 预先感谢。