Spring代理请求属性吗?

Man*_*Row 3 java session spring servlets spring-mvc

如果某个地方我有一个单身@Component豆"富"了@Autowired的HttpSession或HttpServletRequest的,不富本身必须声明会话(或请求)范围的,或者我可以把它作为一个简单的单---在这种情况下HttpSession中和/或HttpServletRequest可能已经通过Spring注入了作为范围代理吗?

Sot*_*lis 7

这是一个非常简单的检查行为的测试(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;
}
Run Code Online (Sandbox Code Playgroud)

@Component
public class Foo {
    @Autowired
    public HttpServletRequest request;
}
Run Code Online (Sandbox Code Playgroud)

如果您发送请求,您将注意到返回的属性始终是null,并且该类是类似的

class com.sun.proxy.$Proxy19
Run Code Online (Sandbox Code Playgroud)

因此,HttpServletRequest即使@Componentbean是单例作用域,您也总是获得不同的对象.


这是解释:

实例化a时WebApplicationContent,它会注册一些特殊ObjectFactory实例来解析底层的某些Web类型BeanFactory.这是完成的WebApplicationContextUtils.registerWebApplicationScopes(..).其中之一是以下内容

beanFactory.registerResolvableDependency(ServletRequest.class, new RequestObjectFactory());
Run Code Online (Sandbox Code Playgroud)

当Spring扫描你的bean并确定它需要自动装配HttpServletRequest(这是一个子类型ServletRequest)字段时,它将在其可解析的依赖关系的地图中查找并得到它RequestObjectFactory.

由于这是一个ObjectFactory与喷射目标是一个接口类型,Spring将创建该类型委托给创建的对象/返回由所述的代理RequestObjectFactory对每个请求.这是完成的AutowireUtils.resolveAutowiringValue(..).

因此,您的Foobean不需要请求作用域.