我一直在寻找一种方法将数据从DB加载到HashMap中,并使该映射可用于所有根资源类和一些其他提供程序类(ContainerRequestFilter的实现更精确)。我找到并实现了一个解决方案,我在其中执行查询并在ServletContextListener的contextInitialized方法中加载地图并将其设置为ServletContext属性:
@WebListener
public class ServletContextCaching implements ServletContextListener {
@Inject
private SomeBeanLocalInterface someBean;
@Override
public void contextDestroyed(ServletContextEvent sce) {
ServletContext context = sce.getServletContext();
context.removeAttribute("CUSTOM_DATA_MAP");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
List<SomeEntity> someEntities = someBean.findAllActive();
Map<String, String> temp = new HashMap<String, String>();
for (SomeEntity e : someEntities) {
temp.put(e.getSomeKey(), e.getSomeValue());
}
ServletContext context = sce.getServletContext();
context.setAttribute("CUSTOM_DATA_MAP", temp);
}
}
在servlet上下文中存储自定义数据(即属性)并因此使其可用于“所有人”是一种好习惯吗?将一些数据从DB加载到REST服务中的内存映射中的建议做法是什么?我很确定我不是第一个需要这个的人:)
答案 0 :(得分:1)
使用应用程序范围存储数据非常常见。您可以使用ServletContext
,但还有其他选择。正如Ashley Frieze已经评论过的那样,您可以使用bean的一个实例并在需要的地方注入它。这将是例如如果使用EJB,则使用CDI或@ApplicationScoped
bean时使用@Singleton
bean。
如果您想要一个没有任何依赖关系的纯JAX-RS解决方案,您可以使用@Context
之类的public class MyApplication extends Application {
public MyApplication(@Context Dispatcher dispatcher) {
MyClass myInstance = new MyClass();
dispatcher.getDefaultContextObjects().put(MyClass.class, myInstance);
}
}
。以下是该示例的副本:
public void get(@Context MyClass myInstance) { ... }
你可以像这样注入你的课程:
{{1}}
如果您要存储大量数据,则described by Bill Burke或infinispan等分布式缓存也可能是一种选择。但对于大多数用例来说可能过大。