Changes between Version 1 and Version 2 of 2017_1
- Timestamp:
- 01/16/2017 04:09:26 PM (9 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
2017_1
v1 v2 1 1.java类中EnvUtils使用优化 2 在Env实例依赖servlet的过滤器,其功能也主要是用于处理servlet请求的工具类,在非Controller类或jsp中使用可能会造成错误。 1 2 == 1.java类中EnvUtils使用优化 == 3 4 5 在servlet处理请求时,EnvFilter中会调用EnvUtils.getEnv()实例化Env,并对实例进行参数设置,这些都是必要步骤,在非Controller类或jsp中使用EnvUtils.getEnv()可能会跳过这些步骤,从而造成程序出错。 3 6 4 7 {{{ … … 31 34 ...... 32 35 info = EnvUtils.getEnv().getBean(GeliDao.class).find(UserPurchasingInfo.class, this.userId); 36 //或者 info = EnvUtils.getEnv().getBean(UserPurchasingInfoService.class).find(this.userId); 33 37 ...... 34 38 } … … 36 40 } 37 41 }}} 38 这种代码至少在三种情况下调用会出现错误:[[BR]] 39 1.在单元测试中[[BR]] 40 2.不依赖于servlet的定时任务中[[BR]] 41 3. 42 这种代码至少在三种情况下调用会出现NullPointerException错误:[[BR]] 43 1.在单元测试中被调用时[[BR]] 44 2.不依赖于servlet的定时任务中被调用时[[BR]] 45 3.在处理servlet的请求时,通过代码发起的新线程中简单的调用EnvUtils.getEnv().getBean(xxx.class)获取某个类的实例会和1、2点一样出现错误。[[BR]][[BR]] 46 47 '''原因'''[[BR]] 48 1、2点的错误原因比较明显,原因是在代码执行的时候没有经过过滤器,EnvUtils.getEnv()只是把Env实例化了,env对象里的servletContext参数是空的,没有进行设置,调用的时候就报空指针异常了。[[BR]] 49 第3点报错的原因是因为EnvUtils.getEnv()用到了线程单例(代码如下),当线程第一次调用时threadLocal会实例一个Env对象,之后这个线程再调用都只返回这个对象,而且只能被这个线程调用,当在处理请求过程中如果新启了线程再调用EnvUtils.getEnv()就会得到一个新的Env实例,这个实例和1、2一样,没有设置env对象里的servletContext参数,调用env.getBean(xxx.class)的时候就会报空指针异常。 42 50 {{{ 43 51 public class EnvUtils { … … 50 58 } 51 59 52 //通过EnvUtils获取的Env实例是线程单例的 60 //通过EnvUtils获取的Env实例是线程单例的,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。 53 61 private static final ThreadLocal<Env> threadLocal = new ThreadLocal<Env>() { 54 62 @Override … … 60 68 } 61 69 }}} 62 70 '''优化方法'''[[BR]] 71 将非Controller的java类中的EnvUtils.getEnv().getBean(GeliDao.class)改为GeliUtils.getDao(),将EnvUtils.getEnv().getBean(xxxService.class)改为SpringCtxUtils.getBean(xxxService.class)。(SpringCtxUtils在cn.pconline.best.util目录下)
![(please configure the [header_logo] section in trac.ini)](http://www1.pconline.com.cn/hr/2009/global/images/logo.gif)