还在用@Autowired注入?试试这个最佳实践

huiyugan
发布于 2022-11-18 11:10
浏览
0收藏

前言

Spring框架本身有各种不同的方式来执行依赖项的注入。灵活的选择是Spring框架的强项。然而,并非所有依赖注入方式都被认为是最佳实践。

依赖注入

接下来我们通过一些代码示例,来分别实现Spring的多种依赖注入的方式。首先我们有一个​​MyService​​​,这个​​service​​​中有一个​​sayHi()​​​的服务,我们在​​Controller​​中尝试用不同的方式进行注入。

@Service
public class MyService{
    public String sayHi(){
        return "hello Spring.";
    }
}

属性注入

@Controller
public class FieldController {

    @Autowired
    private MyService service;

    public String saySomething(){
        return service.sayHi();
    }
}

通过属性注入的方式,Spring会在转配Bean时通过反射注入。这种方式虽然可以满足依赖的注入,但是在测试时,要么需要启动Spring Context,要么使用一些Spring实用程序执行依赖项注入以进行测试。


我们可以通过为私有属性提供setter来改进这一点。getter和setter通常被认为是面向对象编程中的最佳实践。通过注解setter方法来指导Spring使用setter进行依赖项注入是很简单的。

方法注入

@Controller
public class FieldController {

    private MyService service;

    @Autowired
    public void setService(MyService service){
        this.service = service;
    }
    
    public String saySomething(){
        return service.sayHi();
    }    
}

这是对使用私有属性注入的一种改进方式,但是还是会有人认为代码太多。

构造器注入

当使用构造函数注入属性时,必须要提供​​@Autowired​​​注解。这是一个很好的功能,它为我们减少了一些代码。从​​Spring Framework 4.2​​版本开始,用于依赖注入的构造函数注解已经是可选的。

@Controller
public class FieldController {

    private MyService service;

    public FieldController(MyService service){
        this.service = service;
    }
    public String saySomething(){
        return service.sayHi();
    }
}

基于构造器的依赖注入通常被认为是最佳实践。有一段时间,我个人喜欢基于setter的注入,但后来我转而支持基于构造器的注入。


基于构造器的注入方式目前主要还有两个问题。


  • 我们服务的类型是具体类型。硬类型的依赖项注入并不被认为是最佳实践。
  • 我们要注入的属性没有声明为final,因此,从理论上讲,可以在实例化后修改注入的属性。

依赖注入最佳实践

依赖项注入的最佳实践是利用接口、构造函数和final属性。

最佳实践服务接口

public interface BpService {
    String getHello();
}

最佳实践服务实现

@Service
public class BpServiceImpl implements BpService{
    @Override
    public String getHello(){
        return "The Best Hello!";
    }
}

使用Lombok

接下来,使用Lombok项目在依赖注入方面的原因是:


  • 声明接口类型的final属性
  • 使用Lombok所需的args构造函数注解

Lombok Controller

@Controller
@AllArgsConstructor
public class BpController {
    private final BpService bpService;
    public String saySomething(){
        return bpService.getHello();
    }
}

这是一个很好的方式,代码会保持的非常干净。在使用Spring时,经常需要几个自动注入的属性。当需要添加一个bean时,只需声明为final的属性就可以。不需要再添加 ​​@Autowired​​​注解,也不需要添加​​setter​​方法或者构造器。


我在日常编码中使用这种方式已经有一段时间了。这绝对是一件省时的事,并且代码也会变得清晰。

小结

本期我给大家分享了Spring依赖注入的不同方式,主要有:


  • 通过私有属性Autowired注入;
  • 通过setter方法注入;
  • 通过构造器注入;


但是这三种方式都不是最佳实践,我推荐的最佳实践是使用Lombok的@AllArgsConstructor注解,并将需要注入的bean定义为final属性。

分类
已于2022-11-18 11:10:07修改
收藏
回复
举报
回复
    相关推荐