V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
stephCurry
V2EX  ›  Java

SpringMVC 的 Controller 怎么就直接注入 HttpSession 了?

  •  
  •   stephCurry · 2018-09-26 21:03:39 +08:00 · 4390 次点击
    这是一个创建于 2253 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如下:

    @Controller
    public class MyController{
    
        @Autowired
        private HttpSession session;
    
        @RequestMapping("/hello"){
            return "hello world";
        }
    }
    

    通常来说, 注入通过在 xml 声明 Bean 或是 注解 @Component 也好, 就是 setter 或 constructor 也行, 但是 Httpsession 或是 HttpServletRequest 都没有任何注入过程或是声明, 直接用 @Autowired 就使用了.
    有的说 Spring 它给代理了, 但是也查了很多, 找不到完整的解释. 有点困惑..

    10 条回复    2018-09-30 18:05:57 +08:00
    czk1997
        1
    czk1997  
       2018-09-26 22:17:20 +08:00
    你不是用 Spring MVC 和 Spring Web 了吗……不可能每个都让你自己实现一个,一些通用的是写好的。
    stephCurry
        2
    stephCurry  
    OP
       2018-09-26 22:42:20 +08:00
    @czk1997 是啊, 但是就想知道为什么
    vteng
        3
    vteng  
       2018-09-26 23:00:43 +08:00 via Android
    @Controller pubic class MyController(HttpSession session){····}
    Infernalzero
        4
    Infernalzero  
       2018-09-26 23:27:18 +08:00   ❤️ 1
    看 WebApplicationContextUtils 的 registerWebApplicationScopes 方法你就明白了,Spring 注入的并不是严格要求必须是 Spring 的 Bean,对应看 DefaultListableBeanFactory 的 findAutowireCandidates 方法,registerResolvableDependency 接口的注释其实说得很清楚了。此外,Controller 其实也并不一定要求是 Spring 的 bean,Spring 的设计还是非常灵活的
    incompatible
        5
    incompatible  
       2018-09-26 23:44:03 +08:00   ❤️ 1
    注入并非一定要通过 setter 或者 constructor,通过 field 也可以。Java 反射机制可以 list 到所有 field (包括 private )并且改变 field 的 accessibility 的。

    此处注进来的 HttpSession 是一个 proxy,对该 HttpSession 的方法调用会被代理给当前线程对应的 http request 的 session。
    onnfee
        6
    onnfee  
       2018-09-27 09:05:50 +08:00
    神奇的还有呢,这个 session 成员变量还是线程安全的!
    BBCCBB
        7
    BBCCBB  
       2018-09-27 09:19:57 +08:00
    HandlerMethodArgumentResolver. 有啥神奇的
    likaka
        8
    likaka  
       2018-09-27 10:42:45 +08:00
    有 httpsession,却没有 httprequest,当时觉得好奇怪
    stephCurry
        9
    stephCurry  
    OP
       2018-09-27 14:45:43 +08:00
    @Infernalzero 阐述的很通透! 感谢!
    huang1102
        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";
    }
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5229 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 01:15 · PVG 09:15 · LAX 17:15 · JFK 20:15
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.