这是一个检查行为的非常简单的测试(Spring 4.0.0.RELEASE)
@Controller
@RequestMapping("/service")
public class NewController {
@RequestMapping(method = RequestMethod.GET)
public @ResponseBody String test(ModelMap model) {
System.out.println(requestEntity.request.getAttribute("type")); // get it
requestEntity.request.setAttribute("type", "Scope"); // set it so that we can make sure that our second request doesn't contain it
System.out.println(requestEntity.request.getClass());
return "whatever";
}
@Autowired
private Foo requestEntity;
}
和
@Component
public class Foo {
@Autowired
public HttpServletRequest request;
}
如果您发送请求,您会注意到返回的属性始终为null,并且类类似于
class com.sun.proxy.$Proxy19
因此,即使 @Component bean 是单例范围的,您总是会得到不同的 HttpServletRequest 对象。
解释如下:
当您实例化一个WebApplicationContent 时,它会注册一些特殊的ObjectFactory 实例来解析底层BeanFactory 中的一些web 类型。这是在WebApplicationContextUtils.registerWebApplicationScopes(..) 中完成的。其中之一是以下
beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
当 Spring 扫描您的 bean 并确定它需要自动装配 HttpServletRequest(它是 ServletRequest 的子类型)字段时,它将查看其可解析依赖关系的映射并获取此 RequestObjectFactory。
因为这是一个ObjectFactory 并且注入目标是一个接口类型,所以Spring 将创建一个该类型的代理,该代理委托给RequestObjectFactory 在每个请求上创建/返回的对象。这是在AutowireUtils.resolveAutowiringValue(..) 中完成的。
因此,您的 Foo bean 不需要在请求范围内。