zoukankan      html  css  js  c++  java
  • struts1和struts2线程安全对比

    ①,Struts1通过缓存来管理action对象,并且使用了单例模式,就是一个action只产生一个实例对象,这个实例对象要处理所有对应的request,所以Action类里面不应该有可变的全局变量,我们应该把所有的变量都封装到ActionForm里面。

    来看下Struts1的生成action实例对象的源代码:

     1     protected Action processActionCreate(HttpServletRequest request,
     2         HttpServletResponse response, ActionMapping mapping)
     3         throws IOException {
     4         // 获取action类的名字
     5         String className = mapping.getType();
     6 
     7         if (log.isDebugEnabled()) {
     8             log.debug(" Looking for Action instance for class " + className);
     9         }
    10 
    11         Action instance;
    12         
    13         // 加锁处理。
    14         synchronized (actions) {
    15             // 如果此Action已经被创建过对象了,则直接返回已经创建好的对象。
    16             instance = (Action) actions.get(className);
    17 
    18             if (instance != null) {
    19                 if (log.isTraceEnabled()) {
    20                     log.trace("  Returning existing Action instance");
    21                 }
    22 
    23                 return (instance);
    24             }
    25 
    26             // 如果还没有被创建对象,则创建一个再返回。
    27             if (log.isTraceEnabled()) {
    28                 log.trace("  Creating new Action instance");
    29             }
    30 
    31             try {
    32                 instance = (Action) RequestUtils.applicationInstance(className);
    33 
    34                 // Maybe we should propagate this exception
    35                 // instead of returning null.
    36             } catch (Exception e) {
    37                 log.error(getInternal().getMessage("actionCreate",
    38                         mapping.getPath()), e);
    39 
    40                 response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
    41                     getInternal().getMessage("actionCreate", mapping.getPath()));
    42 
    43                 return (null);
    44             }
    45             
    46             // 把新创建好的对象放到缓存中。
    47             actions.put(className, instance);
    48 
    49             if (instance.getServlet() == null) {
    50                 instance.setServlet(this.servlet);
    51             }
    52         }
    53 
    54         return (instance);
    55     }

    从代码中我们可以看出,struts1使用了一个actions的缓存来管理所有的action实例对象,当请求一个action对象时,先到actions里面查找对应的action对象,如果存在,则直接返回此对象,如果不存在,则新创建一个action对象,然后加到缓存中,再返回新创建的action实例对象。

    ②,struts2和struts1不同,struts2会为每个请求都创建一个action对象实例,所以不存在线程安全的问题。

    还是看源码:

    StrutsPrepareAndExecuteFilter类的doFilter方法:

     1     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
     2 
     3         HttpServletRequest request = (HttpServletRequest) req;
     4         HttpServletResponse response = (HttpServletResponse) res;
     5 
     6         try {
     7             prepare.setEncodingAndLocale(request, response);
     8             prepare.createActionContext(request, response);
     9             // 把dispatcher绑定到当前线程上,作为当前线程的局部变量。
    10             prepare.assignDispatcherToThread();
    11             if (excludedPatterns != null && prepare.isUrlExcluded(request, excludedPatterns)) {
    12                 chain.doFilter(request, response);
    13             } else {
    14                 request = prepare.wrapRequest(request);
    15                 ActionMapping mapping = prepare.findActionMapping(request, response, true);
    16                 if (mapping == null) {
    17                     boolean handled = execute.executeStaticResourceRequest(request, response);
    18                     if (!handled) {
    19                         chain.doFilter(request, response);
    20                     }
    21                 } else {
    22                     execute.executeAction(request, response, mapping);
    23                 }
    24             }
    25         } finally {
    26             // 此处清楚线程局部变量。
    27             prepare.cleanupRequest(request);
    28         }
    29     }

    从上面的代码中可以看出,struts2把dispatcher作为局部变量绑定到了线程上,而Dispatcher是struts2的核心分发器,所有的action初始化操作都是在它控制之下,所以struts2是线程安全的。

  • 相关阅读:
    JavaScript设计模式与开发实践
    ECMAScript 6入门
    时间管理微课程:值得永久收藏的25条时间管理技巧
    day14.生成器迭代器作业
    windows下创建MySQL定时备份与删除脚本
    day14.生成器进阶,推导式
    day13.装饰器进阶,迭代器
    day12.生成器;wraps初识
    day11.装饰器初识
    day10.函数升级
  • 原文地址:https://www.cnblogs.com/huashui/p/3220718.html
Copyright © 2011-2022 走看看