开发者学堂课程【Java Web开发系列课程 - Struts2框架入门: ActionContext 二】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/537/detail/7306
ActionContext 二
内容介绍:
一、什么是 ActionContext?
二、获取 ActionContext
三、ActionContext 的简图
四、ThredLocal 模式
五、ActionContext 中包含六大对象
一、什么是 ActionContext?
ActionContext 是 map 结构的容器,ActionContext 是 Action 的上下文,存放Action 执行过程中的数据信息。
ActionContext 存放 Action 的数据、ActionInvocation request 的数据、session 的数据、application 的数据、locale 的数据、conversion errors 等。
每次请求时会为当前线程创建一个新的 ActionContext。而 ActionContext 采用了ThreadLocal 的方式来存放 ActionContext,所以 ActionContext 是线程安全。
二、获取 ActionContext
ActionContext getContext()获取。由于 ActionContext 是线程安全的,并且是通过静态方法获取的,所以在本线程中的非 Action 类中也可以访问。(有些公共数据处理完可以直接放置)
**注意点:ActionContext 是基于请求创建的,所以在非请求的线程中是不能使用ActionContext 对象的。
如:filter 的 init()方法。
三、ActionContext 的简图
在 servlet 中调用 ActionContext 的机会很少,基本上在获取 servlet API、response时会用到,其他地方几乎不使用。
为什么要回到 Action Filter?
public void doFilter(ServletRequest req, ServletResponse res, Filt
er)
HttpservletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
try
{
prepare.setEncodingAndLocale(request, response)
;
prepare.createActionContext(request, respon
se
);
prepare.assignDispatcherToThread()
;
if
(
excludedPatterns
!
= null
&
& prepare.isUrlExcluded
(requs
est)
chain.doFilter(request, response);
} else {
request
=
prepare.wrapRequest(request)
;
ActionMappingmapping
=
prepare. findActionMapping(reque
st);
if (mapping = nul
l
)
{
b
oolean handled
=
execute. executestaticResourcereau
if (
!
handled)
{
chain.doFilter(request, response);
}
else
{
execute.executeAction(request, response, mapping);
}
}
}
finally
{
p
re
p
are. cleanunReauest( reauest
);
}
四、ThredLocal 模式
public class Threadlocal
extends Cbjec
t
该类提供了线程局部(thread--local)变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。
ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。
例如,以下类生成对每个线程唯一的局部标识符。线程 ID 是在第一次调用 U
nique ThreadIdGererator.getC
u
rrent ThreadId()
时分配的,在后续调用中不会更改。
import java, util
.
concurrent, atomic. AtomicIneger
;
private static final AtonicInteger uniqueId
=
n
e
w AtomicInteger(0
);
private static
f
inal ThreadLocal
<
Integer
>
uniquenum
=
new ThreadL
o
cal
() {
@
override proteced Int
e
ger initialvalus
() {
ret
u
rn unique
I
d
.
get
A
ndIncrement
() ;
}
每个线程都保持对其线程局部变量副本的隐式引用,只要线程是活动的并且ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。
从以下版本开始:
1.2
*构造方法摘要
ThreadLocal()
创建一个线程本地变量。
*方法摘要
get(
)
返回此线程局部变量的当前线程副本中的值。
initialvalue
()
返回此线程局部变量的当前线程的“初始值”。
r
enove
()
移除此线程局部变量当前线程的值。
g
et (I val
u
e
)
将此线程局部变量的当前线程副本中的值设置为指定值。
*从类 java.lang.Object 继承的方法
clone, equals, fina
l
ize, get
C
lass, hash
C
ode, notify, rotif
y
All, toString, wait, wait, wait
public class Test
public static void main(
S
tring[ ] args)
{
//Threadlocal 存放线程局部变量的容器
//存放在threadlocal 中的局部变量是线程安全的
final Threadlocal<
S
tring> ac
=
new ThreadLocal(
)
;
ac.set("siggy");
new Thread(new Runnable(
) {
public void run(
) {
System. out. printIn(
“
thread:"
+ac.get()
)
;
} ).start()
;
System. out. printIn(ac. get())
;
*
Returns the ActionContext specific to the current thread
.
*
* @return the ActionContext for the current thread, is never < tt>n
public static ActionContext getContext
() {
return (ActionContext) actionContext. get();
/
/
Don't do lazy context creation, as it requires container;
/
/
precede the context creation
/
/ if (context =
=
null)
//
Value
St
ackvs
=
ValuestackFactory
.
getFactory(
)
.create
V
alue
//
context new ActionContext(vs
.
get Context())
;
//
set Context (context)
;
*
to the speci
fi
ed value. Most subc
l
asses w
ill
have no need to
*
override this method, relying solely on the {@link
#
initialvalue
*
method to set the values of thread
-
locals
.
*
@param value the value to be stored in the current thread's copy l
*
this thread- local
public void set(T value)
{
Thread t= Thread. current Thread()
;
Threadlocal
M
ap map
=
getmap(t);
if (map
!
= null)
map.set(this, value);
createMap(t, value);
}
五、ActionContext 中包含六大对象
application
s
ession
r
equest
p
arameters
a
ttr(page—>request—>session—>application)
*
ValueStack(
值栈
)