spring的bean的作用域有singleton,prototype,session,request等,本来以为很简单,但实际面试中,90%的人根本就不知道如何使用,其中不乏工作5,6年以上的,只知道有这几个作用域,这考验java开发人员de基础。
很多人看教程里面,使用prototype作用域的bean代码里面,获取bean的方法都是用appContext.getBean方法获取,但实际工作编码中,我们一般是通过方法的参数注入。
@Service
@Scope(value="prototype")
public class MainServices
如下,每次注入新的MainServices实例:
@GetMapping("/test3")
public HashMap<String, Object> test2(@Autowired MainServices s) {
}
但要在一个controller里面注入一个多例的service需要怎么实现?(工作中不应该这样用,而是应该通过参数注入)
如下:
@RestController
public class MainController {
@Autowired
MainServices services;
}
很明显controller只有一个,service也有只一个,这样定义是不能达到效果的!自己测试一下就知道。
正确的方法是如下,需要指定使用代理,如果注入的是接口可以用INTERFACES,否则用TARGET_CLASS。
@Service
@Scope(value="prototype", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class MainServices
这样spring就会注入一个代理类,然后每次调用的时候会根据你的作用域去获取bean。只有不是singleton的bean,注入的都是代理类。
很简单的一个知识点,我想说明的是,看教程一定要自己尝试一下,并了解他的工作原理,思考ioc,aop,作用域的关系。
所以你知道为什么在controller里面注入request没有线程安全问题了吧?!
@Autowired
HttpServletRequest request;
这里request返回的是类名是com.sun.proxy.$Proxy62,很明显使用的jdk的动态代理。