本文讨论了在使用IDEA中的Autowired注解时出现警告信息的原因以及替换方案。原因分析包括初始化问题和过度依赖IOC。文章提到,自动装配注入必须在子类构造函数之后进行,否则可能导致空指针异常。此外,@Autowired注解导致应用程序和框架之间存在强绑定,而使用@Resource注解则更加灵活。文章介绍了几种替换方案,包括使用set方法进行注入、使用构造器注入以及使用构造器的简化版(使用lombok)。文章总结指出,在实际使用中,使用构造方法注入是较可行的方法,并且使用lombok可以轻松地实现简化的构造方法。
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
投诉在IDEA中使用@Autowired注解,会提示如下内容,那么为什么会出现以下提示呢?下面我们进一步分析分析

原因分析
关于这个问题,答案其实比较统一,通俗易懂其实也很容易理解。
Java初始化类的顺序:父类静态字段>父类静态代码块>子类静态字段>子类静态代码块>父类成员变量>父类结构代码块>父类构造函数> 子类成员变量 > 子类构造代码块 > 子类构造函数。
自动装配注入必须在子类构造函数之后排队。SpringIOC不会判断依赖bean是否为null,JVM编译时不会有问题,但如果使用不当,运行起来可能会出现空指针异常。
@Autowired由 Spring 提供,而@Resource由 JSR-250 提供,这是一个 Java 标准。前者会警告,后者不会,因为前者导致应用程序和框架之间存在强绑定。如果换成别的IOC框架,就无法注入成功。其实对于这方面,我觉得大部分情况下不会有什么问题。
我在网上看到了一些其他方面的总结,比如:依赖太多但不够明显,违反了单一职责原则;immutable objects不能像constructors之类的注入,这类问题需要结合个人实际开发判断。
对于@Autowired的使用,虽然强绑定了业务代码和框架,但是字段注入确实大大简化了代码。追求完全松耦合其实过于理想化,在实际使用中应该追求一个平衡,否则过度追求松耦合得不偿失。
替换方案
除了使用@Autowired,也可以使用@Resource替换@Autiwired方法就是其中之一。只需要修改一个注解,可以看到,修改后,警告信息就没有了

下面再介绍几种其它方式
set方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @RestController public class TestAutoController {
ITestAutoService testAutoService;
@Autowired public void setTestAutoService(ITestAutoService testAutoService) { this.testAutoService = iTestAutoService; }
@GetMapping("/getTestAtuo") public Result<TestAutoDto> getAuto() { return testAutoService.getAuto(); } }
|
该方法也使用了@Autowired注解,但作用于成员变量的Setter函数,而不是像Fied注入那样作用于成员变量。
构造器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @RestController public class TestStructController {
ITestStructService testStructService;
public TestStructController(ITestStructService testStructService) { this.testStructService = iTestStructService; }
@GetMapping("/getTestStruct") public Result<TestStructDto> getStruct() { return testStructService.getStruct(); } }
|
它的优点是使用构造函数注入,这需要对象创建的顺序,它将避免循环依赖问题,是比较可靠的方法。
构造器的简化版(lombok)
引入maven依赖
1 2 3 4 5
| <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency>
|
然后,我们可以在创建时使用@RequiredArgsConstructor注释,这将帮助我们创建一个构造函数,final关键字是必不可少的。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RestController @RequiredArgsConstructor public class TestArgsController {
private final ITestArgsService testArgsService;
@GetMapping("/getArgs") public Result<?> getArgs() { return testArgsService.getArgs(); } }
|
总结
在使用中,使用构造的方法是比较可行的,而有了lombok,实际上可以非常轻松地实现。