springboot中获取request的方式

方法一:Controller中加入参数

@Controller
public class TestController { 

  @RequestMapping("/test")
​  public void test(HttpServletRequest request) throws InterruptedException {        
    // 模拟程序执行了一段时间*        
    Thread.sleep(1000); 
  }
}

线程安全

缺点,传参安全,但是每个方法都需要写一遍的话非常麻烦

方法二:Autowired自动注入

@Controller public class TestController{ 
     
    @Autowired 
    private HttpServletRequest request; //自动注入request*    
    
    @RequestMapping("/test")    
    public void test() throws InterruptedException{
      //模拟程序执行了一段时间*        
      Thread.sleep(1000);    
    }
}

线程安全

分析:在Spring中,Controller的scope是singleton(单例),也就是说在整个web系统中,只有一个TestController;但是其中注入的request却是线程安全的,原因在于:使用这种方式,当Bean(本例的TestController)初始化时,Spring并没有注入一个request对象,而是注入了一个代理(proxy);当Bean中需要使用request对象时,通过该代理获取request对象。

代理对象中用到了 ThreadLocal , 因此request对象也是线程局部变量;这就保证了request对象的线程安全性。

优缺点:

1.不限于Controller中,可以在任何地方进行注入;

2.注入的对象不限于request:除了注入request对象,该方法还可以注入其他scope为request或session的对象,如response对象、session对象等;并保证线程安全

3.但是如果controller有好多,那么我们注入就得写N多,比较麻烦

方法三:基类中自动注入
 

public class BaseController {   

 @Autowired 
 protected HttpServletRequest request;
}

线程安全,

优缺点:

与方法2相比,避免了在不同的Controller中重复注入request;但是考虑到java只允许继承一个基类,所以如果Controller需要继承其他类时,该方法便不再好用。

方法4:手动调用

@Controller
public class TestController {

    @RequestMapping("/test")
    public void test() throws InterruptedException {
        HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest();
        // 模拟程序执行了一段时间
        Thread.sleep(1000);
    }
}

线程安全

优缺点:

可以在非Bean中直接获得。缺点,如果用的地方多,写起来十分繁琐

总结
综上所述,Controller中加参数(方法1)、自动注入(方法2和方法3)、手动调用(方法4)都是线程安全的,都可以用来获取request对象。如果系统中request对象使用较少,则使用哪种方式均可;如果使用较多,建议使用自动注入(方法2 和方法3)来减少代码冗余。如果需要在非Bean中使用request对象,既可以在上层调用时通过参数传入,也可以直接在方法中通过手动调用(方法4)获得。


————————————————
版权声明:本文为CSDN博主「无尽征途」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_30893635/article/details/115528339

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐