ThreadLocal to store ServletRequest and Response in servlet: what for?

后端 未结 8 731
情歌与酒
情歌与酒 2020-12-05 21:19

Once I have came across a pattern, where ServletRequest and response objects are put to servlet\'s local ThreadLocal variables. The servlet class h

8条回答
  •  [愿得一人]
    2020-12-05 21:45

    Since the request and the response objects are stored in thread local variables, you get thread safe access to those objects without having to pass them around as method parameters.

    Example 1: Without thread local

    public class MyServlet extends Servlet {
        private MyObject myObject = new MyObject();
    
        public void service(ServletRequest request, ServletResponse response) {
            myObject.doSomething(request, response);
        }
    }
    
    public class MyObject {
        private MyOtherObject myOtherObject = new MyOtherObject();
        public void doSomething(ServletRequest request, ServletResponse response) {
            // I do nothing with request/response, but need to accept them in order
            // to pass them to myOtherObject
            myOtherObject.doSomethingElse(request, response);
        }
    }
    
    public class MyOtherObject {
        public void doSomethingElse(ServletRequest request, ServletResponse response) {
            // Do something else with request / response
        }
    }
    

    Example 2: with thread local

    public class MyServlet extends Servlet {
        private MyObject myObject = new MyObject();
    
        private static ThreadLocal currentRequest = new ThreadLocal();
    
        public static ServletRequest getCurrentRequest() {
            return currentRequest.get();
        }
    
        private static ThreadLocal currentResponse = new ThreadLocal();
    
        public static ServletResponse getCurrentResponse() {
            return currentResponse.get();
        }
    
        public void service(ServletRequest request, ServletResponse response) {
            ...
            currentRequest.set(request);
            currentResponse.set(response);
            ...
            myObject.doSomething();
        }
    }
    
    public class MyObject {
        private MyOtherObject myOtherObject = new MyOtherObject();
        public void doSomething() {
            // I do not need to know about request / response as I do nothing with them
            myOtherObject.doSomethingElse();
        }
    }
    
    public class MyOtherObject {
        public void doSomethingElse() {
            // Now I can get the current request / response in a thread safe
            // manner and without having to accept them as parameters
            ServletRequest request = MyServlet.getCurrentRequest();
            ServletResponse response = MyServlet.getCurrentResponse();
    
            // Do something with request / response
        }
    }
    

    Obviously, for simple servlets just passing the objects around is the easiest thing, but in complex scenarios it is sometimes useful to have one static but thread safe getter.

提交回复
热议问题