在一项要求中,我们必须通过网络应用程序提供某些属性,以便我们可以在我们想要的地方显示它们。所以我们几乎没有选择
我们计划创建一个带有一些静态字段的实用程序类,这些字段将在应用程序启动时或在该列表的第一个请求到达时分配值。
想法是读取属性文件并创建List<String>
并将其分配给静态字段,以便当有人需要访问它时,他/她需要以下调用
GeneralUtil.getList()
由于我们正在使用Web应用程序,因此可以选择创建一个类似
的列表器public final class MyListener
implements ServletContextListener {
}
然后读取contextInitialized
方法上的属性文件,并将读取值分配给静态字段,以便它们在启动后可用。
其他选择是
在GeneralUtil
类中创建一个静态块,并将文件读取逻辑放在静态块中,这样一旦cotainer静态字段加载的类将被初始化,我们就不需要为后续请求加载它。
我的问题是哪些应该是首选方法,如果还有其他最好的方法来实现这一点。我想避免将List放在ApplicationContext
或任何此类方法中。
答案 0 :(得分:4)
我会使用ServletContextListener
方法和您的财产的访问者。它比静态初始化程序块更清晰,更直观。
如果将来你想将初始化逻辑分成几个方法,我会发现它也更容易。在具有明确责任的单独班级中,比在一些“GeneralUtil上帝之类”中更容易(和阅读!)。
如果你只限于Servlets,我认为这是最好最简单的解决方案。
但是,如果您正在使用EJB,那么您也可以将@Singleton
EJB与@Startup
一起使用。如果您正在使用CDI,则可以使用@ApplicationScoped
CDI bean。
HTH。
答案 1 :(得分:2)
然后在contextInitialized方法上读取属性文件,并将读取值分配给静态字段,以便它们在启动后可用。
而不是静态变量,将创建的List<String>
放在servletContext
对象contextInitialized(ServletContextEvent sce)
方法
请注意,您可以从servletContext
检索ServletContextEvent
对象。
答案 2 :(得分:1)
静态解决方案意味着ThreadLocal并使用序列化。
应用程序作用域bean(是的,可能最好放在ApplicationContext中)最有意义。你仍然可以将它包装在一种GeneralUtil包装器中。 Piotr Nowicki的解决方案是最好的。
我想你不想听到这个解决方案。
答案 3 :(得分:1)
为什么不想在ApplicationContext中添加这些值?这是有意义的,因为它对整个应用程序都是一样的吗?
在你提到的两个选项中,最好在MyListener中加载这些属性而不是静态块,如果加载失败则推断你的GeneralUtil类不会被加载,除非你特意捕获异常并忽略它,这意味着不能使用应用程序。
答案 4 :(得分:0)
我已经将ServletContextListener用于类似的用例,并且它运行得很好。我认为这是最简单,最直接的解决方案。只需将属性放入ServletContext
setAttribute(name, object)
,然后通过getAttribute(name)
在应用中的任意位置检索它们。