
如下:
@Controller public class MyController{ @Autowired private HttpSession session; @RequestMapping("/hello"){ return "hello world"; } } 通常来说, 注入通过在 xml 声明 Bean 或是 注解 @Component 也好, 就是 setter 或 constructor 也行, 但是 Httpsession 或是 HttpServletRequest 都没有任何注入过程或是声明, 直接用 @Autowired 就使用了.
有的说 Spring 它给代理了, 但是也查了很多, 找不到完整的解释. 有点困惑..
1 czk1997 2018-09-26 22:17:20 +08:00 你不是用 Spring MVC 和 Spring Web 了吗……不可能每个都让你自己实现一个,一些通用的是写好的。 |
2 stephCurry OP @czk1997 是啊, 但是就想知道为什么 |
3 vteng 2018-09-26 23:00:43 +08:00 via Android @Controller pubic class MyController(HttpSession session){} |
4 Infernalzero 2018-09-26 23:27:18 +08:00 看 WebApplicationContextUtils 的 registerWebApplicationScopes 方法你就明白了,Spring 注入的并不是严格要求必须是 Spring 的 Bean,对应看 DefaultListableBeanFactory 的 findAutowireCandidates 方法,registerResolvableDependency 接口的注释其实说得很清楚了。此外,Controller 其实也并不一定要求是 Spring 的 bean,Spring 的设计还是非常灵活的 |
5 incompatible 2018-09-26 23:44:03 +08:00 注入并非一定要通过 setter 或者 constructor,通过 field 也可以。Java 反射机制可以 list 到所有 field (包括 private )并且改变 field 的 accessibility 的。 此处注进来的 HttpSession 是一个 proxy,对该 HttpSession 的方法调用会被代理给当前线程对应的 http request 的 session。 |
6 uuau 2018-09-27 09:05:50 +08:00 神奇的还有呢,这个 session 成员变量还是线程安全的! |
7 BBCCBB 2018-09-27 09:19:57 +08:00 HandlerMethodArgumentResolver. 有啥神奇的 |
8 likaka 2018-09-27 10:42:45 +08:00 有 httpsession,却没有 httprequest,当时觉得好奇怪 |
9 stephCurry OP @Infernalzero 阐述的很通透! 感谢! |
10 huang1102 2018-09-30 18:05:57 +08:00 你应该有在 web.xml 配置了监听 , 才能在普通类中直接注入这个 <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> spring Mvc 要接收参数有: 1 HttpServletRequest 2 HttpServletResponse 3 HttpSession 4 Model 5 请求参数 可以不用注入的 @Controller public class MyController{ // @Autowired // private HttpSession session; @RequestMapping("/hello") //你漏了方法名称 public String helloWorld(HttpSession session){ return "hello world"; } } |