当前位置:   article > 正文

Spring的实例化和依赖注入时机与延迟实例化_springboot controller什么时候实例

springboot controller什么时候实例

原文链接:https://blog.csdn.net/xfx_1994/article/details/103873129?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

Spring的实例化

使用@Autowired可以注入一个bean进来

  1. @Autowired
  2. private Diana diana;

那么如果在容器中没有Diana的对象被实例化的时候应用程序会报错吗?我们可以通过把Diana上面的@Component注释掉来看一下结果如何

  1. //@Component
  2. public class Diana {
  3. public void r(){
  4. System.out.println("Diana R");
  5. }
  6. }
  7. @RestController
  8. @RequestMapping("/v1/banner")
  9. public class BannerController {
  10. @Autowired
  11. private Diana diana;
  12. }

启动SpringBoot会出现以下结果:
在这里插入图片描述

由此可见,如果spring无法在容器中找到Diana的对象,在默认的机制下启动时就会直接报错。

当在@Autowired后面加上 (required = false),变成

  1. @RestController
  2. @RequestMapping("/v1/banner")
  3. public class BannerController {
  4. @Autowired(required = false)
  5. private Diana diana;
  6. @GetMapping("/test")
  7. public String test1() {
  8. diana.r();
  9. return "Hello test1";
  10. }
  11. }

SpringBoot可以 正常启动,但是当访问diana下面的方法时会出现下面这样的结果

在这里插入图片描述

出现这样的情况注入是没有问题的,而是由于容器中没有diana这个对象却又调用diana下面的方法

结论:
_如果spring无法在容器中找到Diana的对象,在默认的机制下启动时就会直接报错。我们可以通过@Autowired(required = false)的方式令应用程序可以正常启动。 _

依赖注入时机
IOC容器究竟是在什么时候实例化对象并把对象注入到代码片段里的呢?是当请求访问Controller的时候才进行实例化并注入,还是在SpringBoot应用启动时就开始实例化并把对象注入到代码片段的呢?

由之前的代码可以看出,当把Diana上面的@Component注释掉时,SpringBoot应用启动时应用程序会立即报错,我们也可以通过在Diana这个类中加一个无参的构造方法来验证以下
 

  1. @Component
  2. public class Diana {
  3. public Diana() {
  4. System.out.println("Hello Diana");
  5. }
  6. public void r(){
  7. System.out.println("Diana R");
  8. }
  9. }

应用程序启动时控制台打印出了"Hello Diana"

在这里插入图片描述

结论:
默认机制下,在SpringBoot应用启动时,IOC容器就开始实例化对象并把对象注入到代码片段里

延迟实例化

SpringBoot默认是立即实例化的机制,我们可以通过 @Lazy让它变成延迟实例化。

  1. @Component
  2. @Lazy
  3. public class Diana {

在这里插入图片描述

当只在Diana上加上 @Lazy,启动应用却发现Diana仍然是立即实例化,@Lazy并没有起作用。这是因为BannerController是立即实例化的,那它下面的属性如果是@Autowired的就也需要立即实例化,只加在Diana上的 @Lazy是会被忽略掉的。如果真的需要延迟实例化就需要在BannerController也加上@Lazy或者是BannerController注入Diana的地方加上@Lazy,示例代码如下:
 

  1. @RestController
  2. @RequestMapping("/v1/banner")
  3. @Lazy
  4. public class BannerController {

或者

  1. @Autowired
  2. @Lazy
  3. private Diana diana;

当访问当前的Controller控制台打印出了下面的结果:

在这里插入图片描述

由此可见,此时是当请求访问Controller的时候才进行实例化并注入

如果没有特殊理由最好不要开启延迟实例化。使用默认机制提前实例化才是一个比较好的做法,因为可以尽早发现问题,避免很多问题在运行时才被发现。

原文链接:https://blog.csdn.net/xfx_1994/article/details/103873129?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Cpp五条/article/detail/66308?site
推荐阅读
相关标签
  

闽ICP备14008679号