使用特殊的自动启动 servlet 在启动时进行初始化并共享应用程序数据
我需要获取一些配置并连接到某个地方的外部资源/对象/系统并将其存储在应用程序范围中。
我可以看到两种设置应用程序的方法:
- 覆盖现有 servlet 中的
init()
以及那里所需的代码,并将所有构造的对象保留在同一个 servlet 中。 - 拥有某种初始化 servlet 并使用其
init()
来完成工作。然后将创建的对象存储在 ServletContext 中,以便与我的其他 servlet 共享。
上述哪种方法更好?有没有更好的方法在 servlet 之间共享对象?直接互相打电话或者这样……?
I need to get some configuration and connect to external resources/objects/systems somewhere and store it in application scope.
I can see two ways to setup my application:
- Overriding the
init()
in the existing servlets and required code there and keeping all constructed objects inside that same servlet. - Having some kind of an initialisation servlet and using its
init()
to do the work. Then storing created objects inServletContext
to share it with my other servlets.
Which out of above is better approach? Is there any better way to share objects between servlets? Calling them directly from one another or so...?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
两者都不是更好的方法。 Servlet 旨在侦听 HTTP 事件(HTTP 请求),而不是侦听部署事件(启动/关闭)。
CDI/EJB 不可用?使用
ServletContextListener
如果您还没有 Servlet 3.0,无法升级(大概是时候了,因为 Servlet 3.0 已经十多年前推出了),因此无法使用
@WebListener
注解,那么你需要手动在/WEB-INF/web.xml
中注册它,如下所示:要存储和获取应用程序范围内的对象(以便所有 servlet 都可以访问它们),请使用
ServletContext#setAttribute()< /code>
和
#getAttribute()
。下面是一个示例,它让侦听器将自身存储在应用程序范围中:
然后在 servlet 中获取它:
在 JSP EL 中也可以通过
${config}
获得它。所以你也可以把它变成一个简单的 bean。CDI可用吗?使用
@Observes
关于ApplicationScoped.class
这可以在 servlet 中通过
@Inject
获得。如有必要,还可以将其设置为@Named
,以便在 EL 中也可以通过#{config}
来使用它。应该注意的是,这是自 CDI 1.1 以来的新内容。如果您仍使用 CDI 1.0 并且无法升级,请选择其他方法。
如果您好奇如何在 Tomcat 等非 JEE 服务器上安装 CDI,请前往:如何在Tomcat上安装和使用CDI?
EJB可用吗?考虑
@Startup
@Singleton
这个可通过
@EJB
在 servlet 中使用。与其他方法的区别在于,它默认是事务性的,并且在 @Singleton 的情况下也是读/写锁定。因此,如果您需要将随机 EJB(例如@Stateless
)注入到@WebListener
或@ApplicationScoped
中,那么您基本上可以像很好地将两者合并到一个@Startup @Singleton
中。另请参阅:
None of both is the better approach. Servlets are intended to listen on HTTP events (HTTP requests), not on deployment events (startup/shutdown).
CDI/EJB unavailable? Use
ServletContextListener
If you're not on Servlet 3.0 yet and can't upgrade (it would be about time because Servlet 3.0 was introduced more than a decade ago), and thus can't use
@WebListener
annotation, then you need to manually register it in/WEB-INF/web.xml
like below:To store and obtain objects in the application scope (so that all servlets can access them), use
ServletContext#setAttribute()
and#getAttribute()
.Here's an example which lets the listener store itself in the application scope:
and then obtain it in a servlet:
It's also available in JSP EL by
${config}
. So you could make it a simple bean as well.CDI available? Use
@Observes
onApplicationScoped.class
This is available in a servlet via
@Inject
. Make it if necessary also@Named
so it's available via#{config}
in EL as well.Noted should be that this is new since CDI 1.1. If you're still on CDI 1.0 and can't upgrade, then pick another approach.
In case you're curious how to install CDI on a non-JEE server such as Tomcat, head to: How to install and use CDI on Tomcat?
EJB available? Consider
@Startup
@Singleton
This is available in a servlet via
@EJB
. The difference with other approaches is that it's by default transactional and in case of@Singleton
also read/write locked. So if you would ever need to inject a random EJB (e.g.@Stateless
) into a@WebListener
or an@ApplicationScoped
then you could basically as good merge both into a single@Startup @Singleton
.See also: