spe*_*key 13 java spring spring-mvc
据我所知,默认情况下是Spring MVC单例中的控制器.HttpServletRequest传递给控制器处理程序方法.而且它的确定,虽然HttpServletRequest是在请求范围内,但我经常看到HttpServletRequest获取@Autowired到控制器领域,就像这样:
@Controller("CMSProductComponentController")
@RequestMapping(CMSProductComponentController.CONTROLLER_PATH)
public class CMSProductComponentController {
    @Autowired
    private HttpServletRequest request;
}
这可能是个问题吗?更一般的问题:如果将一个reqeust-scoped组件注入单例中会发生什么?
Sot*_*lis 14
不,因为HttpServletRequest它不会是一个问题,它不应该用于其他请求范围的bean.基本上,Spring将生成一个HttpServletRequest包含某种ObjectFactory(RequestObjectFactoryfor HttpServletRequest)(YMMV)的代理,该代理知道如何检索实际的实例.当您使用此代理的任何方法时,它们将委派给该实例.
更重要的是,这是懒惰的,所以在初始化时不会失败.但是,如果在没有可用请求时(或者如果您尚未注册RequestScope),则尝试使用bean时,它将失败.
以下是对评论的回应并总体上澄清.
关于XML等价物的proxy-mode属性@Scope,默认值为 ScopedProxyMode.NO.但是,正如javadoc所述
当与非单例作用域实例一起使用时,此代理模式通常不常用,如果要将其用作依赖项,则应优先使用INTERFACES或TARGET_CLASS代理模式.
对于请求范围的bean,此proxy-mode值将不起作用.您需要根据所需的配置使用INTERFACESOR TARGET_CLASS.
随着scope设置为request(使用常量WebApplicationContext.SCOPE_REQUEST),Spring将使用RequestScope它
依赖于螺纹结合的
RequestAttributes实例,这可以通过出口RequestContextListener,RequestContextFilter或DispatcherServlet.
我们来看一个这个简单的例子吧
@Component
@Scope(proxyMode = ScopedProxyMode.INTERFACES, value = WebApplicationContext.SCOPE_REQUEST)
public class RequestScopedBean {
    public void method() {}
}
...
@Autowired
private RequestScopedBean bean;
Spring将生成两个 bean定义:一个用于注入的bean,一个是singleton,另一个用于在每个请求上生成的请求范围bean.
从这些bean定义中,Spring将使用目标类的类型将单例初始化为代理.在这个例子中,就是这样RequestScopedBean.代理将包含在需要时生成或返回实际bean所需的状态,即.在代理上调用方法时.例如,何时
bean.method();
叫做.
此状态基本上是对BeanFactory请求范围的bean定义的基础和名称的引用.它将使用这两个来生成一个新bean,然后调用method()该实例.
该文档的状态
Spring IoC容器不仅管理对象(bean)的实例化,还管理协作者(或依赖关系)的连接.如果要将(例如)HTTP请求作用域bean注入另一个bean,则必须注入AOP代理来代替作用域bean.也就是说,您需要注入一个代理对象,该对象公开与范围对象相同的公共接口,但也可以从相关范围(例如,HTTP请求)检索真实的目标对象,并将方法调用委托给真实对象.
所有急切加载的请求范围bean,如果实现正确,将是代理.类似地,没有急切加载的请求范围bean将自己代理或通过代理加载.如果没有HttpSerlvetRequest绑定到当前线程,这将失败.基本上,对于请求范围的bean,bean依赖关系链中的某个地方需要代理.
| 归档时间: | 
 | 
| 查看次数: | 8968 次 | 
| 最近记录: |