Spring依赖注入的几种方式

使用Spring实现依赖注入

可实现的方式有3种:

属性注入
Setter注入
构造方法注入

属性注入:

在属性声明之前添加@Autowired注解

  • 该类必须是Spring管理对象的
public class UserController{
    @Autowired
    private IUserService userService;
}

优点:简单便捷,直观
缺点:在属性上使用@Autowired是不安全的,在执行单元测试(不依赖于任何非测试环境,包括Spng环境,如果加载了非测试环境,则称之为:集成测试)时,由于不加载Spring环境,属性将不会被注入值,则相关代码会出现NPE(NullPointerException),或者,无论是任何原因导致未加载Spring环境的运行,都会导致NPE!

Setter注入:

在需要被Spring调用的Setter方法的声明之前添加@Autowired注解(该类必须是Spring管理对象的)

public class UserController{
    private IUserService userService;
    @Autowired
    public void setUserService(IUserService userService){
        this.userServcie = userService;
    }
}

配置类中的@Bean方法也是Spring自动调用的,Spring也会尝试从容器中查找匹配的对象并用于调用@Bean方法

  • 优点:直观,相比属性注入,安全性略有提升
    • 即使属性是orivatel的,在没有加载Spring环境时,也可以手动调用Setter方法,以避免出现NPE问题
      • 将属性声明为private:是开发规范,应该遵守
  • 缺点:相对麻烦,且没有彻底解决安全问题
    • 增减属性都要做相应的调整
    • 如果使用lombok,源代码中根本没有Setter)方法,无法添加注解
    • 在没有加载Spring环境时,如果没有手动调用Setter方法,仍会导致NPE

构造方法注入:

  • 在需要被Spring调用的构造方法的声明之前添加@Autowired注解

    • 该类必须是Spring管理对象的,演示代码中将不体现这部分代码

      public class UserController{
          private IUserService userService;
          @Autowired
          public UserController(IUserService userService){
              this.userServcie = userService;
          }
      }
      
    • 仅当类中有多个构造方法时才需要添加该注解,如果仅有1个构造方法,Spring会自动调用

  • 优点:能保障安全性

    • 如果构造方法是唯一的,任何环境下都是必须调用的,不会出现在NPE问题
  • 缺点:不直观,相对麻烦

    • 构造方法的参数列表可能很长
    • 必须结合构造方法,才可以明确哪些属性将被注入值
    • 必须保证构造方法唯一
    • 增减属性都要做相应的调整

总结:

理论:

  • 使用@Autowired时,可以通过属性注入、Setter注入和构造方法注入这3种方式,Spring本身并不关心你使用哪种方式,只要使用方式没有问题,都是可以装配的
    • 理论上的选取原则:构造方法注入>Setter注入>属性注入
      • 如果构造方法是唯一的,任何环境下都是必须调用的,不会出现在NPE问题
      • 如果属性是private的,有Setter方法时,即使不加载Spring环境,也可以手动调用,以避免出现NPE问题
      • 如果属性是privatel的,没有可为属性赋值的构造方法,也没有Setter方法,当不加载Spring环境时,必然出现NPE问题

面试答案:

  • 使用Spring实现依赖注入时,可实现的方式有3种:属性注入,Setter注入,构造方法注入。

  • 如果项目对代码安全性的要求不是特别高,可以使用属性注入,因为编写代码非常便利,并且直观,哪些属性会被注入值,一目了然,但这种做法并不安全,当不加载Spring环境时,例如执行单元测试时,会出现NPE问题,即出现安全问题;Setter注入方式比较中庸,并且使用lombok时不可行,并不推荐使用;理想的方式是使用构造方法注入,可以彻底杜绝NPE安全问题,但是需要保证类中仅有1个将用于对各需要注入值的属性赋值的构造方法,而且,会导致构造方法的参数列表可能很长,并且,必须结合构造方法,才可以明确哪些属性将被注入值,增减属性都需要做相应的调整,总的来说,相对麻烦,编写代码成本略高,总的来说,虽然安全,但缺点也比较多,是对代码安全性的要求非常高时的唯一方案。

你可能感兴趣的:(框架,spring)