前言

在使用Spring框架,引用Service时采用@Autoried时,Idea编译器会提示Field injection is not recommended,SpringTeam给出的解决方案为Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies,翻译过来的意思是在bean中始终使用基于构造函数的依赖项注入。请始终使用断言强制依赖。本文将介绍如何解决这个问题。

解决方案

使用Lombok的@RequiredArgsConstructor注解

Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注解实现这一目的。

引入Lombok

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>${lombok.version}</version>
</dependency>

应用层&服务层

// 使用lombok提供的注解工具
@RequiredArgsConstructor
@RestController
public class TestController {
    private final TestService testService;
    
    @RequestMapping("test")
    public void test() {
        testService.get();
    }
}

public interface TestService {
    void get();
}

@Service
public class TestServiceImpl implements TestService {
    void get() {
        //todo something
    }
}

分析

根据资料,依赖注入有三种形式:

  • 变量(filed)注入
@Autowired
private TestService testService;
  • 构造器注入
private final TestService testService;

@Autowired
public TestController(TestService testService) {
    this.testService = testService;
}
  • set方法注入
private final TestService testService;

@Autowired
public void setTestService(TestService testService) {
    this.testService = testService;
}

三种之间比较:

  • 变量注入非常简洁,没有多余的代码,无论有几个依赖都只需要使用@Autowired进行注入,提高JAVA代码的简洁性。
  • 但是变量注入不能有效的指明依赖,如果启动容器时,依赖的类没有注入到Spring中,那么使用@Autowired会导致这个类无法运作,程序不能正常启动。如果使用@Autowired(required=false),则可能导致使用方法时出现NPE。
  • 采用set方式注入时,依赖可有可无,即使没有注入这个依赖,也不会影响整个类的运行。
  • 采用构造器方式必须显示注明必须强制注入,通过强制指明依赖注入保证整个类的运行。

NPE:Null Point Exception 空指针异常

总结:

尽量减少使用变量注入的方式,尽可能使用构造器注入或set方法注入。如果是强制依赖则优先使用构造器注入方式,否则使用set方法注入的方式。