ThreadLoacl的反思

在我的随笔 spring mvc:注解@ModelAttribue妙用  中使用ThreadLocal来简化spring mvc控制层controller中的ModelMap,Response、Json数据封装结构的声明。

这种方式很明显地可以减少方法参数以及变量数量,于是乎,我在每个新系统上都将上述一套搬了过去!

经过一段时间,(经人指点)发现会有以下问题:

  1. 因为没有在每个线程结束后清除变量,在线程池(比如:tomcat线程池)的作用下就会出现脏数据;
  2. Json数据封装结构其实每次只在返回客户端的时候使用,没必要使用ThreadLocal,在Json数据封装结构中定义一个静态方法即可

定义如下(类名称:JsonData):

 1     /**
 2      * 静态工厂方法
 3      * 
 4      * @return
 5      */
 6     public static JsonData newInstance() {
 7         return new JsonData();
 8     }
 9 
10 /**
11      * 设置成功json
12      * 
13      * @param message
14      * @return
15      */
16     public static JsonData successJson(String message) {
17         return successJson(null, message);
18     }
19 
20     /**
21      * 设置成功的json
22      * 
23      * @param data
24      * @return
25      */
26     public static JsonData successJson(Object data) {
27         JsonData jsonData = newInstance();
28         jsonData.setSuccessJson(data);
29         return jsonData;
30     }
31 
32     /**
33      * 设置成功的json
34      *
35      * @param data
36      */
37     public void setSuccessJson(Object data) {
38         setSuccessJson(data, null);
39     }

使用如下:

 1  @RequestMapping("/xx/list")
 2     @ResponseBody
 3     public JsonData list(@ModelAttribute final DataQuery query) {
 4         try {
 5             //逻辑
 6             return JsonData.successJson(queryResult);
 7         } catch (Exception e) {
 8             LOGGER.error("查询异常", e);
 9             return JsonData.exceptionJson("查询异常");
10         }
11     }

这样不仅可以达到减少代码的目的,另外也去除了线程脏数据问题,也更加简洁明了!

事实上,这是一个很小的问题,却暴露了一个问题:一旦掌握一个新的技能,在未详细论证的情况下就开始使用,是极其危险的!

posted @ 2017-08-23 17:42  雨中漫步,惟情而已  阅读(548)  评论(0编辑  收藏  举报