IDEA为什么不推荐使用@Autowired注解
一、初始化问题
先看一下Java初始化类的顺序:
父类的静态字段 > 父类静态代码块 > 子类静态字段 > 子类静态代码块 > 父类成员变量 > 父类构造代码块 > 父类构造器 > 子类成员变量 > 子类构造代码块 > 子类构造器
而@Autowired注入,则要排队到子类构造器以后,Spring IOC并不会对依赖的bean是否为null做判断,JVM编译时同样也不会有问题,但如果使用不当,运行起来时或许会出现空指针异常。
二、对IOC容器依赖过强
@Autowired由Spring提供,而@Resource是JSR-250提供的,它是Java标准。前者会警告,而后者不警告,就是因为前者导致了应用与框架的强绑定,若是换成其他IOC框架,则不能够成功注入了。其实对于这方面,我认为在大多数情况时是不会有什么问题的。
三、其他方面
我看到网络上有一些其他方面的总结,比如:
依赖过多却不够明显,违反了单一职责原则;不能像构造器那样注入不可变的对象等,这类问题需要结合个人实际开发进行判断。
对于@Autowired使用方面,它虽然是将业务代码和框架进行了强绑定,但字段注入确实大幅简化了代码。
追求完完全全的松耦合其实也过于理想化,应该在实际使用中追求平衡,否则将为了过度追求松耦合而得不偿失。
四、其他解决方案
set方法注入
这种方法也使用了@Autowired注解,但是它是作用于成员变量的Setter函数上,而不是像Fied注入一样作用于成员变量上。
@RestController
public class TestController2 {
ITestService testService;
/*
* 基于set注入
* */
@Autowired
public void setTestService(ITestService iTestService) {
this.testService = iTestService;
}
@GetMapping("/status2")
public Result<?> status() {
return testService.status();
}
}构造器注入
它的好处在于,采用了构造方法注入,这种方式对对象创建的顺序会有要求,它将避免循环依赖问题。是最可靠的方法。
@RestController
public class TestController1 {
ITestService testService;
/*
* 基于构造方法的注入
* */
public TestController1(ITestService iTestService) {
this.testService = iTestService;
}
@GetMapping("/status1")
public Result<?> status() {
return testService.status();
}
}构造器注入简化版
首先,需要引入lombok依赖。使用@RequiredArgsConstructor注解,它将帮我们创建构造器,final关键字必不可少。
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> </dependency>
@RestController
@RequiredArgsConstructor
public class TestController3 {
/*
* 用@RequiredArgsConstructor注解,这个使用方式也可以应用于service层
* */
private final ITestService testService;
@GetMapping("/status3")
public Result<?> status() {
return testService.status();
}
}在使用中,使用构造方法是比较可行的,加上lombok,使用@RequiredArgsConstructor注解,其实也可以到达非常简便。
总结为一张表
版权声明
非特殊说明,本文由Zender原创或收集发布,欢迎转载。
ZENDER

发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。