查看原文
其他

使用 @Autowired 为什么会被 IDEA 警告,应该怎么修改最佳?

点击关注 👉 Java技术迷 2023-05-06

点击关注公众号,Java干货及时送达

作者:赵昕彧

来源:blog.csdn.net/qq_40579464/article/details/129006885


# 问题原因


关于这个问题,其实答案相对统一,实际上用大白话说起来也容易理解。


1.初始化问题


先看一下Java初始化类的顺序:父类的静态字段 > 父类静态代码块 > 子类静态字段 > 子类静态代码块 > 父类成员变量 > 父类构造代码块 > 父类构造器 > 子类成员变量 > 子类构造代码块 > 子类构造器。


而Autowired注入,则要排队到子类构造器以后了,SpringIOC并不会对依赖的bean是否为null做判断,JVM编译时同样也不会有问题,但如果使用不当,运行起来时或许会因为出现空指针异常。


2.对IOC容易依赖过强


@Autowired由Spring提供,而@Resource是JSR-250提供的,它是Java标准。前者会警告,而后者不警告,就是因为前者导致了应用与框架的强绑定,若是换成其他IOC框架,则不能够成功注入了。其实对于这方面,我认为在大多数情况时是不会有什么问题的。


3.其他方面


我看到网络上有一些其他方面的总结,比如:依赖过多却不够明显,违反了单一职责原则;不能像构造器那样注入不可变的对象等,这类问题需要结合个人实际开发进行判断。


对于@Autowired使用方面,它虽然是将业务代码和框架进行了强绑定,但字段注入确实大幅简化了代码。追求完完全全的松耦合其实也过于理想化,应该在实际使用中追求平衡,否则将为了过度追求松耦合而得不偿失。


# 其他使用方式


除了使用@Autowired以外,我们其实也有几种好用的方式。使用@Resource替代@Autiwired方法是其中一种,只需要改变一个注解,这里就不展示了。


set方法

@RestControllerpublic class TestController2 { ITestService testService; /* * 基于set注入 * */ @Autowired public void setTestService(ITestService iTestService) { this.testService = iTestService; } @GetMapping("/status2") public Result<?> status() { return testService.status(); }}

这种方法也使用了@Autowired注解,但是它是作用于成员变量的Setter函数上,而不是像Fied注入一样作用于成员变量上。


构造器

@RestControllerpublic class TestController1 { ITestService testService; /* * 基于构造方法的注入 * */ public TestController1(ITestService iTestService) { this.testService = iTestService; } @GetMapping("/status1") public Result<?> status() { return testService.status(); }}

它的好处在于,采用了构造方法注入,这种方式对对象创建的顺序会有要求,它将避免循环依赖问题。是最可靠的方法。

构造器的简化版(推荐)


首先,需要引入lombok依赖。

<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version></dependency>

随后,我们在创建时就可以使用@RequiredArgsConstructor注解,它将帮我们创建构造器,final关键字必不可少。

@RestController@RequiredArgsConstructorpublic class TestController3 { /* * 用@RequiredArgsConstructor注解,这个使用方式也可以应用于service层 * */ private final ITestService testService; @GetMapping("/status3") public Result<?> status() { return testService.status(); }}

我们在使用这些创建方法时,都可以调出IDEA的结构(Structure)面板进行查看,如下图所示。



可以看到,在这个类中,已经存在我们所需要注入的内容。


在网上有博主总结了一张表,但因为到处能看到,不知原来出处是哪里。


# 总结


在使用中,使用构造方法是比较可行的,加上lombok,其实也可以到达非常简便。


  

1、社区纠纷不断:程序员何苦为难程序员?

2、该死的单元测试,写起来到底有多痛?

3、互联网人为什么学不会摆烂

4、为什么国外JetBrains做 IDE 就可以养活自己,国内不行?区别在哪?

5、相比高人气的Rust、Go,为何 Java、C 在工具层面进展缓慢?

6、让程序员早点下班的《技术写作指南》

点在看

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存