Spring框架自己具备多种执行依赖项注入的方式。 选项的灵活性是Spring框架的优点。 可是,并不是全部的依赖项注入选项都被视为最佳实践。 有些实际上很是贫穷。java
我为咱们提供了一些示例,以审查必须使用的各类依赖项注入选项。编程
让咱们以Spring Service为例。 就咱们的目的而言,该服务具备一个返回字符串的方法。 咱们将使用“服务”,并使用Spring将其注入某些人造控制器中。 请记住,咱们只是在探索如何使用Spring Framework进行依赖项注入架构
Java框架
1 @Service 2 3 public class MyService { 4 5 public String getHello(){ 6 7 return "Hello"; 8 9 } 10 11 }
咱们的现场控制员拥有一项服务的公共财产。 咱们能够注释该字段,Spring将注入该服务的实例。ide
Java函数
1 @Controller 2 3 public class FieldController { 4 5 @Autowired 6 7 MyService myService; 8 9 public String saySomething(){ 10 11 return myService.getHello(); 12 13 } 14 15 }
这只是一个公共财产,没有二传手。 显然,这不是一个好习惯。 也不推荐。学习
咱们能够对此进行一些改进,并将对该字段的访问权限设为私有。 Spring Framework确实容许你自动链接私有字段。 你确实看到有人这样作。 Spring将执行一些反射魔术来执行依赖项注入。测试
Javaui
@Controller this
1 public class PrivateFieldController { 2 3 @Autowired 4 5 private MyService myService; 6 7 public String saySomething(){ 8 9 return myService.getHello(); 10 11 } 12 13 } 14 15
尽管比仅使用私有字段更好,可是测试变得头疼。 你要么须要启动Spring Context,要么使用一些Spring实用程序来执行依赖注入以进行测试。 不是世界末日,而是使人讨厌的。
咱们能够经过为私有财产提供二传手来改善这一点。 Getter和Setter一般被认为是面向对象编程中的最佳实践。 经过注释setter方法来指示Spring使用setter进行依赖项注入很简单。
Java
1 @Controller 2 3 public class SetterController { 4 5 private MyService myService; 6 7 @Autowired 8 9 public void setMyService(MyService myService) { 10 11 this.myService = myService; 12 13 } 14 15 public String saySomething(){ 16 17 return myService.getHello(); 18 19 } 20 21 }
这是使用私有字段时的明显改进。 有人会抱怨这太多代码了。 但实际上,自South Park第一季以来,此类任务已在现代IDE中实现了自动化。
下一个选项是使用构造函数。 到目前为止,这是咱们研究过的最佳方法。 使用构造函数设置注入的属性时,没必要提供自动装配注释。 这是一个很好的功能,能够节省一些键入时间。 从Spring Framework版本4.2开始,用于依赖项注入的构造函数的注释是可选的。
Java
1 @Controller 2 3 public class ConstructorController { 4 5 private MyService myService; 6 7 public ConstructorController(MyService myService) { 8 9 this.myService = myService; 10 11 } 12 13 public String saySomething(){ 14 15 return myService.getHello(); 16 17 } 18 19 }
基于构造函数的依赖注入无疑被认为是最佳实践。 曾经有一段时间我我的偏心基于setter的注入,可是后来我转向了基于构造函数的注入。
咱们仍然能够改善咱们的榜样。 如今有两个主要问题。 第一,咱们的服务类型是具体类型。 硬类型的依赖注入不是最佳实践。
第二个问题是咱们注入的属性未声明为final。 所以,从理论上讲,该类能够在实例化注入的属性后对其进行修改。
依赖项注入的最佳实践是利用接口,构造函数和最终属性。
我已经创建了一个“最佳实践”服务界面,并提供了一个服务实现,该服务实现带有Spring Service注释。
Java
1 public interface BpService { 2 3 String getHello(); 4 5 }
Java
1 @Service 2 3 public class BpServiceImpl implements BpService { 4 5 @Override 6 7 public String getHello() { 8 9 return "The Best Hello!"; 10 11 } 12 13 }
如今,使用Project Lombok进行依赖注入最佳实践的秘诀在于:
如今,Project Lombok将为声明为final的全部属性生成一个构造函数。 Spring会自动使用Lombok提供的构造函数来自动装配该类。
Java
1 @RequiredArgsConstructor 2 3 @Controller 4 5 public class BpFinalConstructorController { 6 7 private final BpService bpService; 8 9 public String saySomething(){ 10 11 return bpService.getHello(); 12 13 } 14 15 }
这是执行此操做的真正好方法。 你的代码保持很是干净。 使用Spring时,一般须要多个自动装配属性。
当你须要添加另外一个bean时,只需声明一个final属性。
若是你重构而且再也不须要Spring托管的依赖项,则只需删除final属性。
你再也不须要维护设置器或构造函数代码。 龙目岛计划减轻了你的负担。
我如今在平常编码中一直使用这种技术。 绝对是节省时间。 并致使更干净的代码。 未使用的属性和未使用的构造函数参数已一去不复返了。 如今,重构的痛苦就减轻了一点!