如题:为什么在SpringMVC和SpringBoot中可以直接注入HttpServletRequest对象。
代码示例
@Autowired
private HttpServletRequest request;
@GetMapping(value = "/rest/current")
public ReturnResult current() {
System.out.println(request.getRequestURL().toString());
JSONObject res = new JSONObject();
res.put("requestId", UUID.randomUUID().toString());
res.put("datatime", DateUtils.getDatetime());
return ReturnResult.get(res);
}
理论上,我们需要注入其他包中的对象的时候,是必须在@Configuration修饰的类下面使用@Bean进行方法修饰的才行的,如下所示:
@Configuration
public class ApplicationConfig {
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
那为什么HttpServletRequest这个对象如此优秀,可以直接注入呢?
它这么秀的根本原因是因为……注入的并不是真正的 HttpServletRequest,只是一个代理对象,其背后的核心对象是
org.springframework.web.context.support.WebApplicationContextUtils.RequestObjectFactory
你看这个类长啥样:
那这个“当前 ServletRequest”从哪来呢?
Servlet 除了
ServletContextListener
之外,还有一个ServletRequestListener
:只要你注册了这个,就能在请求前执行
requestDestroyed
Spring 弄了一个
org.springframework.web.context.request.RequestContextListener
,在这个里面获取并存储的