webx 中request 对象作为单例注入的实现

webx 文档中描述:
你不能把一个短期的对象如request、response和request context注入到MyAction这个singleton对象。然而,在Webx中,这样做是可以的!奥秘在于Request Contexts服务对上表所列的这些短期对象作了特殊的处理,使它们可以被注入到singleton对象中。事实上,被注入的只是一个“空壳”,真正的对象是在被访问到的时候才会从线程中取得的。http://openwebx.org/docs/filter.html

1public class MyAction {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private HttpServletResponse response;

    @Autowired
    private ParserRequestContext parser;
}

例2public class ManagerHsf {
    @Resource
    HttpServletRequest request;

    @Resource
    private HankService hankService;

问题来了, 这个request 的空壳是如何实现,执行request.getParameter(xxx), request.setParameter(xxx)时,到真正的request中取值的。
1、注入的request对象 是HttpServletRequest

EnhancerByCGLIB
56fdd100 类的一个实例, 重复多次http请求,发现这个对象的id 始终不变,都是624, 显然这里注入的request 对象是一个单例的对象。

技术分享
2、我们观察request.getParameter(xxx)执行时的,线程堆栈情况,如下,在执行getParameter(xxx) 首先碰到了一个拦截器SpringExtUtilProxiedInterceptorcom.alibaba.citrus.service.requestcontext.impl.RequestContextBeanFactoryPostProcessorRequestProxyTargetFactory.getObject()获取到真正的request对象。
技术分享

public class RequestContextBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  private static class RequestProxyTargetFactory implements ProxyTargetFactory {
        public Object getObject() {
            RequestAttributes requestAttrs = RequestContextHolder.currentRequestAttributes();

            HttpServletRequest request = ((ServletRequestAttributes) requestAttrs).getRequest();



            return request;
        }
    }
    ....
}
public abstract class RequestContextHolder  {

    private static final ThreadLocal requestAttributesHolder = new NamedThreadLocal("Request attributes");

    private static final ThreadLocal inheritableRequestAttributesHolder =
            new NamedInheritableThreadLocal("Request context");

public static RequestAttributes currentRequestAttributes() throws IllegalStateException {
        RequestAttributes attributes = getRequestAttributes();
        return attributes;
    }
    public static RequestAttributes getRequestAttributes() {
        RequestAttributes attributes = (RequestAttributes) requestAttributesHolder.get();
        if (attributes == null) {
            attributes = (RequestAttributes) inheritableRequestAttributesHolder.get();
        }
        return attributes;

    ......
}

从上面代码中有两个ThreadLocal 对象, 真正的request 对象, 是通过, RequestContextHolder的静态方法,获取得到,当前线程关联的 ”ServletRequestAttributes“对象, 而获取到的。

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。