Java Spring代理请求属性吗?

Java Spring代理请求属性吗?,java,spring,session,spring-mvc,servlets,Java,Spring,Session,Spring Mvc,Servlets,如果在某个地方我有一个带有自动连线HttpSession或HttpServletRequest的singleton@组件bean“Foo”,Foo本身是否必须声明为session(或request)作用域,或者我可以把它作为一个简单的单例——在这种情况下,HttpSession和/或HttpServletRequest可能已经通过Spring作为作用域代理注入了?我的理解是Spring确实使用了代理,是的。Spring允许您通过向singleton中注入代理,将请求或会话范围的对象注入singl

如果在某个地方我有一个带有自动连线HttpSession或HttpServletRequest的singleton
@组件
bean“Foo”,Foo本身是否必须声明为session(或request)作用域,或者我可以把它作为一个简单的单例——在这种情况下,HttpSession和/或HttpServletRequest可能已经通过Spring作为作用域代理注入了?

我的理解是Spring确实使用了代理,是的。Spring允许您通过向singleton中注入代理,将请求或会话范围的对象注入singleton范围对象

对于SpringMVC,我认为注入的代理由
ThreadLocal
变量支持,因为每个请求都绑定了一个线程。然后,真正的
HttpServletRequest
就可以通过这个注入的代理获得,该代理在调用时委托给
ThreadLocal


因此,您不需要将“Foo”声明为会话或请求作用域,并且可以将其保持为单例。

这里有一个非常简单的测试来检查行为(Spring 4.0.0.RELEASE)

如果发送请求,您会注意到返回的属性总是
null
,并且类类似于

class com.sun.proxy.$Proxy19
因此,即使
@Component
bean是单例作用域的,您总是会得到一个不同的
HttpServletRequest
对象


解释如下:

当您实例化
WebApplicationContent
时,它会注册一些特殊的
ObjectFactory
实例,用于解析基础
BeanFactory
中的某些web类型。这是在
webapplicationcontextuals.registerWebApplicationScopes(..)
中完成的。以下是其中之一

beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
当Spring扫描bean并确定需要自动连接
HttpServletRequest
(这是
ServletRequest
)字段的子类型时,它将查看其可解析依赖项的映射,并获得此
RequestObjectFactory

因为这是一个
ObjectFactory
,注入目标是一个接口类型,所以Spring将创建一个该类型的代理,该代理将委托给
RequestObjectFactory
在每个请求上创建/返回的对象。这是在
AutowireUtils.resolveAutowiringValue(..)
中完成的

因此,您的
Foo
bean不需要限定请求范围

class com.sun.proxy.$Proxy19
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());