创建自己的ActionContext对象简化开发

在Webwork和Struts2框架中,ActionContext扮演了全局上下文的功能。无论是在JSP页面、Action类、或是其他诸如Service、DAO或工具类中,都可以通过这个类提供的方法,来访问诸如Request、Session等范围对象,以及所谓的“值栈(ValueStack)”对象。该类内部采用ThreadLocal保存当前线程的实例,因此使用时只需要调用ActionContext.getContext()方法即可访问当前线程的上下文。而在实际应用中,我们还可以自己根据需要创建类似的Context对象,来实现对上下文变量的封装。

 

 

由上述代码可见,对于每个线程,调用AppContext都会返回相同的实例。但是,只能获得实例还不够,还必须添加访问上下文变量的方法:

 

 

这样一个基本的Context类就有了。下面要解决的就是Context中的变量在何时,通过何种方式设定到Context中的问题。

 

通常,会有一个Filter,当请求进入时,该Fileter会将当前请求相关的变量,如Response,Request,Session等等设定到当前线程的Context对象中。如果是我们自己编写Context类的话,可能也需要编写一个实现类似功能的Filter类。


比如,我在开发公司的CMS系统的时候,需要频繁访问诸如项目(Project),模板(Template),栏目(Column)......等等对象。而在请求时,往往会有诸如?pid=3&tid=4&cid=5之类的请求参数。此时便开发一个CMSContext类,通过Filter根据请求参数将当前请求相关的项目信息、模板信息和栏目信息设定到Context类中。之后,无论在JSP页面还是在JAVA类中,只要通过



就可以直接获得当前请求相关的项目、模板和栏目信息,而不需要在Action、Service和DAO之间传递pid、tid和cid。

这样一方面简化了方法方法声明,加快了开发速度,另一方面,提供了访问环境变量的一致方法,提高了代码的规范性。

 

除了可以采用Filter预设变量以外,这种模式还可以更加灵活地加以运用,不仅可以通过与Filter来实现全局上下文,还可以在局部的复杂调用过程中充当上下文。

 

再有一点需要注意的是就是关于线程继承的问题。大多数应用环境都是单线程的,也就是说所有处理都在当前请求线程内进行。但有时,可能会出现需要创建子线程的情况。在这种情况下,在子线程内调用Context.getContext()方法将获得新的(未初始化的)上下文对象,因为ThreadLocal中保存的是子线程的Context实例,而非父线程的。

 

要解决这种问题,就需要在Context类中使用InheritableThreadLocal来代替ThreadLocal:

 

 

这样,在当前线程中创建的子线程就也能通过Context.getContext()的方式访问父线程中的上下文变量了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值