有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java Web应用程序:使用单例模式的servlet线程安全

我希望能从PHP/Laravel的背景(大约8年前,我在大学里学习过Java),开始使用Java进行web应用程序编程

我已经玩了一段时间,对大多数基本概念(如Servlet和Servlet容器)以及一些流行的web服务器/Servlet容器技术(如Jetty、Tomcat等)都感到相当满意。我还尝试对Java EE进行了大量研究

既然我想积累这方面的知识,我不想使用任何框架,事实上我想把建立自己的框架作为一种学习练习。然而,我也仔细研究了一些框架,比如Spring MVC、Struts、Play和Vaadin等

所以我建立了一个Maven项目,我建立了一个web.xml文件,指向我创建的一个servlet,我希望在我的“框架”中建立一个入口点

src/main/webapp/WEB-INF/WEB。xml

<servlet>
    <servlet-name>Application</servlet-name>
    <servlet-class>com.mypackage.Application</servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>Application</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

src/main/java/com/mypackage/Application。java

package com.mypackage;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class Application extends HttpServlet {
    @Override
    public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 
    }
}

所以现在我想制作自己的IoC容器,使用singleton模式(我知道这通常是不鼓励的,被认为是一种反模式),以便从应用程序的其他部分轻松访问它:

src/main/java/com/mypackage/Container。java

package com.mypackage;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class Container {
    private static Container instance;

    public static Container make(HttpServletRequest request, HttpServletResponse response) {
        return instance = new Container();
    }

    public static Container getInstance() {
        if (instance == null) {
            // Throw an exception
        }

        return instance;
    }

    private Container(HttpServletRequest request, HttpServletResponse response) {
        // ...
    }
}

我想为每个请求/响应周期(或每个servlet)创建一个容器对象,作为我的应用程序的入口点。所以我想做这样的事情:

@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Container container = Container.make(request, response);

    // Do stuff with container and eventually respond to the client
}

现在我知道,当涉及servlet时,线程安全是一个问题,servlet实例上的属性在线程之间共享,但我的问题具体涉及我使用singleton模式和线程安全创建的容器对象

我当前的方法被认为是线程安全的吗?如果没有,为什么,以及如何使其线程安全?请记住,我并不希望我的容器实例在每个线程之间共享,而是希望每个传入的请求/响应都有一个单独的容器

在servlet类的service方法中创建一个新对象,然后让这个新对象创建容器的实例,这是线程安全的(还是推荐的方法)?e、 g

public class Something {
    public Something(HttpServletRequest request, HttpServletResponse response) {
        Container.make(request, response);
    }
}



@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Something something = new Something(request, response);

    // Do stuff with container and eventually respond to the client
}

最后,假设由于servlet容器重复使用servlet实例而产生线程安全问题,我是否正确?根据Java EE documentation

The life cycle of a servlet is controlled by the container in which the servlet has been deployed. When a request is mapped to a servlet, the container performs the following steps.

If an instance of the servlet does not exist, the web container

Loads the servlet class.

Creates an instance of the servlet class.

Initializes the servlet instance by calling the init method. Initialization is covered in Initializing a Servlet.


共 (0) 个答案