【问题标题】:guice servlet is not a singletonguice servlet 不是单例
【发布时间】:2012-10-20 06:22:39
【问题描述】:

发生了可怕的事情

我的项目中有 2 个 servlet - 其中一个只有一个 post 方法并负责处理文件上传。我最近添加了另一个 - 它有一个 get 和一个 post 方法。

这是第二个 servlet 代码

@Singleton
@WebServlet("/Medical_Web")
public class XXXDetailsServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    @Inject
    private Provider<XXXPersistenceManager> persistenceManager;

    @Inject
    private Provider<XXXChain> chainProvider;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        System.out.println("servlet address = " + this);
        final String xxx= request.getParameter("xxx");
        String json = "";
        try {
            final XXXBean xxxBean = persistenceManager.get().find(xxx);
            json = new GsonBuilder().create().toJson(xxxBean);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        request.setAttribute("json", json.trim());
        getServletContext().getRequestDispatcher("/XXX.jsp").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        System.out.println("servlet address = " + this);
        final String xxx = request.getParameter("xxx");
        try {
            final XXXChain chain = chainProvider.get();
            chain.getContext().setAttribute(XXX_TYPE, XXXType.DELETE);
            final XXXBean xxxBean = persistenceManager.get().find(xxx);
            final List<XXXBean> xxxList = new ArrayList<XXXBean>();
            xxxList.add(xxxBean);
            chain.process(xxxList);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

现在 - 这就是让我感动的东西

出于某种原因 - 即使这被标记为 @Singleton - servlet 地址肯定会以不同的方式返回。当我在我的 post 方法中点击一个空指针时,我最初注意到了这一点——每当我调用 get 方法时,我返回的 servlet 实例都会填充所有字段。每当我调用 post 方法时,我返回的 servlet 实例(它是一个不同的实例)没有填充字段(只是 null,好像它们没有被注入)。

我真的很难弄清楚这里发生了什么。似乎这个 servlet 的一个实例是在 guice 上下文之外创建的。如果重要的话——我们使用的是 JBoss 7.1

(对不起所有的XXX,不知道我是否可以发布真实姓名)


这是我的 guice 设置的其余部分

public class XXXServletContextListener extends GuiceServletContextListener {

    @Override
    protected Injector getInjector() {
        return Guice.createInjector(new XXXUploadModule(), new XXXServletModule());
    }
}

这里是 servlet 模块

public class XXXServletModule extends ServletModule {

    @Override
    protected void configureServlets() {
        serve("/xxx1").with(XXXDetailsServlet.class); // this one fails on post
        serve("/xxx2").with(XXXUploadServlet.class);  // this one works 
    }
}

【问题讨论】:

    标签: java servlets dependency-injection guice guice-servlet


    【解决方案1】:

    我不熟悉 Guice servlet 集成的工作原理,但是拥有 @WebServlet("/Medical_Web") 注释意味着您的 Web 容器还将实例化该 servlet 以服务请求。一堆其实没有单例的概念。

    我猜你只需要删除注释并让ServletModule 控制 servlet 生命周期。

    【讨论】:

    • +1,XXXDetailsS​​ervlet其实是Guice作用域中的一个单例,但是这里是由容器直接实例化的。
    • 非常感谢 - 解决了它。
    猜你喜欢
    • 1970-01-01
    • 2012-01-06
    • 1970-01-01
    • 2013-07-09
    • 2013-09-29
    • 2012-08-02
    • 2012-02-24
    • 2012-03-21
    • 1970-01-01
    相关资源
    最近更新 更多