使用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:是开发规范,应该遵守
- 即使属性是orivatel的,在没有加载Spring环境时,也可以手动调用Setter方法,以避免出现NPE问题
- 缺点:相对麻烦,且没有彻底解决安全问题
- 增减属性都要做相应的调整
- 如果使用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问题
- 理论上的选取原则:构造方法注入>Setter注入>属性注入
面试答案:
-
使用Spring实现依赖注入时,可实现的方式有3种:属性注入,Setter注入,构造方法注入。
-
如果项目对代码安全性的要求不是特别高,可以使用属性注入,因为编写代码非常便利,并且直观,哪些属性会被注入值,一目了然,但这种做法并不安全,当不加载Spring环境时,例如执行单元测试时,会出现NPE问题,即出现安全问题;Setter注入方式比较中庸,并且使用lombok时不可行,并不推荐使用;理想的方式是使用构造方法注入,可以彻底杜绝NPE安全问题,但是需要保证类中仅有1个将用于对各需要注入值的属性赋值的构造方法,而且,会导致构造方法的参数列表可能很长,并且,必须结合构造方法,才可以明确哪些属性将被注入值,增减属性都需要做相应的调整,总的来说,相对麻烦,编写代码成本略高,总的来说,虽然安全,但缺点也比较多,是对代码安全性的要求非常高时的唯一方案。