使用Spring实现依赖注入时,可实现的方式有3种:
1. 属性注入
2. Setter注入
3. 构造方法注入
属性注入
在属性的声明之前添加@Autowired注解.注意:该类必须是Spring管理对象的,也是就是说这个类必须是在组件扫描的包范围之内,并且这个类上面还得加注解
优点: 简单便捷、直观
缺点: 在属性上使用@Autowired是不安全的,在执行单元测试(不依赖于任何非测试环境,包括Spring环境,如果加载了非测试环境,将称之为: 集成测试)时,由于不加载Spring环境,属性将不会被注入值,则相关代码会出现NPE(NullPointerException),或者,无论是任何原因导致未加载Spring环境的运行,都会导致NPE
Setter注入
在需要被Spring调用的Setter方法的声明之前添加@Autowired注解,该类必须是Spring管理对象的
配置类中的@Bean方法也是Spring自动调用的,Spring也会尝试从容器中查找匹配的对象并用于调用@Bean方法
优点: 直观,相比属性注入,安全性略有提升(即使属性是private的,在没有加载Spring环境时,也可以手动调用Setter方法,以避免NPE问题)
缺点: 相对麻烦,且没有彻底解决安全问题(增减属性都要做相应的调整;如果使用lombok,源代码中根本没有Setter方法,无法添加注解;在没有加载Spring环境时,如果没有手动调用Setter方法,依然会导致NPE)
构造方法注入
在需要被Spring调用的构造方法的声明之前添加@Autowired注解,该类必须是Spring管理对象的
仅当类中有多个构造方法时才需要添加该注解,如果仅有一个构造方法,Spring会自动调用(也就不需要加该注解)
优点: 能保障安全性(如果构造方法时唯一的,任何环境下都是必须调用的,不会出现NPE问题)
缺点: 不直观,相对麻烦(构造方法的参数列表可能很长;必须结合构造方法,才可以明确哪些属性将被注入值;必须保证构造方法唯一;增减属性都要做相应的调整)
Spring本身并不关心你使用哪种方式,只要使用方式没有问题,都是可以注入的
理论上的选取原则: 构造方法注入>Setter注入>属性注入
Spring官方在VSP(VMware Spring Professional)培训文档中明确指出: Spring doesn't care(can use either),Contructor injection is generally preferred