访问Spring会话范围的代理Bean

时间:2011-02-18 10:01:42

标签: java spring struts2 javabeans

我正在使用带有Spring 3后端的Struts 2开发一个Web应用程序。我正在使用Spring aop:代理bean来处理我的会话bean而不是Struts 2 SessionAware接口。一切都工作正常,直到我有一个在Struts ExecAndWait拦截器下运行的Action。因为这个拦截器实际上是在一个单独的线程下运行我的动作,当我来尝试访问我的代理会话bean时,我得到一个BeanCreationException / IllegalStateException。在这种情况下,是否还有另一种“弹簧方式”可以抓住我的会话bean?

问候

3 个答案:

答案 0 :(得分:3)

来自Execute and Wait Interceptor文档

  

重要:由于操作将在单独的线程中运行,因此您无法使用ActionContext,因为它是ThreadLocal。这意味着如果您需要访问例如会话数据,则需要实现SessionAware而不是调用ActionContext.getSession()。

会话作用域bean的问题在于它们依赖于RequestContextListenerRequestContextFilter设置的线程本地属性。但是后者允许你设置非常有趣的threadContextInheritable标志......

如果您的ExecAndWait拦截器为其服务的每个请求创建新线程,则可继承的线程本地应该将会话范围的bean传播到子线程。但是,如果Struts使用线程池(更可能的是,我没有使用Struts2多年)来提供这些请求,这将产生非常意外和危险的结果。您可以试验这个标志,也许它会起作用。

答案 1 :(得分:0)

您可以使用Spring实现自己的ExecAndWait拦截器。您还可以将此操作的管理/创建委派给Spring。稍后详细介绍了S2 spring插件文档。

答案 2 :(得分:0)

您可以使用RequestContextHolder(Holder类以线程绑定的RequestAttributes对象的形式公开Web请求。),以使子线程可以使用会话范围的代理bean。

定义自定义ExecuteAndWait拦截器,并在doIntercept方法中使用RequestContextHolder中的以下静态方法

  

public static void setRequestAttributes(RequestAttributes attributes, boolean inheritable

     

将给定的RequestAttributes绑定到当前线程。

     

参数:               attributes - 要公开的RequestAttributes,或者为null以重置线程绑定的上下文                inheritable - 是否将RequestAttributes公开为子线程可继承(使用InheritableThreadLocal)

示例代码

public class CustomExecuteAndWaitInterceptor extends ExecuteAndWaitInterceptor {

    @Override
    protected String doIntercept(ActionInvocation actionInvocation) throws Exception {
         RequestAttributes requestAtteiAttributes = RequestContextHolder.getRequestAttributes(); //Return the RequestAttributes currently bound to the thread. 
         RequestContextHolder.setRequestAttributes(requestAtteiAttributes, true);
       //do something else if you want ..
        return super.doIntercept(actionInvocation);

    }   
}