Spring注解驱动开发第21讲——你还不会使用@Resource注解和@Inject注解吗?那你就out了!!
发布日期:2021-06-30 17:56:09 浏览次数:2 分类:技术文章

本文共 4561 字,大约阅读时间需要 15 分钟。

写在前面

在前一讲中,我介绍了如何使用@Autowired、@Qualifier以及@Primary这三个注解自动装配Spring组件。那除了这三个注解以外,还有没有其他的注解可以自动装配组件呢?那必须有啊!今天,我们就一起来说说@Resource注解和@Inject注解。

简单介绍一下@Resource和@Inject这俩注解

@Resource注解

@Resource注解是Java规范里面的,也可以说它是JSR250规范里面定义的一个注解。该注解默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,那么默认取字段名将其作为组件的名称在IOC容器中进行查找,如果注解写在setter方法上,那么默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的一点是,如果name属性一旦指定,那么就只会按照名称进行装配。

我们先看一下@Resource注解的源码,如下所示。

在这里插入图片描述

@Inject注解

@Inject注解也是Java规范里面的,也可以说它是JSR330规范里面定义的一个注解。该注解默认是根据参数名去寻找bean注入,支持Spring的@Primary注解优先注入,@Inject注解还可以增加@Named注解指定要注入的bean。

我们先看一下@Inject注解的源码,如下所示。

在这里插入图片描述
温馨提示,要想使用@Inject注解,需要在项目的pom.xml文件中添加如下依赖,即导入javax.inject这个包。

javax.inject
javax.inject
1

实战案例

测试@Resource注解

首先,我们将项目中的BookService类标注在bookDao字段上的@Autowired注解和@Qualifier注解注释掉,然后添加上@Resource注解,如下所示。

package com.meimeixia.service;import javax.annotation.Resource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;import com.meimeixia.dao.BookDao;@Servicepublic class BookService {
// @Qualifier("bookDao") // 要让首选装配起效果,@Qualifier自然就不能用了// @Autowired(required=false) @Resource private BookDao bookDao; public void print() {
System.out.println(bookDao); } @Override public String toString() {
return "BookService [bookDao=" + bookDao + "]"; } }

然后,我们运行一下IOCTest_Autowired类中的test01()方法,输出的结果信息如下所示。

在这里插入图片描述
可以看到,使用@Resource注解也能够自动装配组件,只不过此时自动装配的是lable为1的bookDao,而不是我们在MainConfigOfAutowired配置类中配置的优先装配的lable为2的bookDao。MainConfigOfAutowired配置类中配置的lable为2的bookDao如下所示。

package com.meimeixia.config;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.Primary;import com.meimeixia.dao.BookDao;/** *  * @author liayun * */@Configuration@ComponentScan({
"com.meimeixia.service", "com.meimeixia.dao", "com.meimeixia.controller"})public class MainConfigOfAutowired {
@Primary @Bean("bookDao2") public BookDao bookDao() {
BookDao bookDao = new BookDao(); bookDao.setLable("2"); return bookDao; }}

这也进一步说明,@Resource注解和@Autowired注解的功能是一样的,都能实现自动装配,只不过@Resource注解默认是按照组件名称(即属性的名称)进行装配的。虽然@Resource注解具备自动装配这一功能,但是它是不支持@Primary注解优先注入的功能的,而且也不能像@Autowired注解一样能添加required=false属性。

我们在使用@Resource注解时,可以通过@Resource注解的name属性显示指定要装配的组件的名称。例如,我们要想装配lable为2的bookDao,只需要为@Resource注解添加 name="bookDao2"属性即可,如下所示。

package com.meimeixia.service;import javax.annotation.Resource;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;import com.meimeixia.dao.BookDao;@Servicepublic class BookService {
// @Qualifier("bookDao") // 要让首选装配起效果,@Qualifier自然就不能用了// @Autowired(required=false) @Resource(name="bookDao2") private BookDao bookDao; public void print() {
System.out.println(bookDao); } @Override public String toString() {
return "BookService [bookDao=" + bookDao + "]"; } }

接着,我们再次运行IOCTest_Autowired类中的test01()方法,输出的结果信息如下所示。

在这里插入图片描述
可以看到,此时输出了lable为2的bookDao,说明@Resource注解可以通过name属性显示指定要装配的bean。

测试@Inject注解

在BookService类中,将@Resource注解注释掉,添加@Inject注解,如下所示。

package com.meimeixia.service;import javax.annotation.Resource;import javax.inject.Inject;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.beans.factory.annotation.Qualifier;import org.springframework.stereotype.Service;import com.meimeixia.dao.BookDao;@Servicepublic class BookService {
// @Qualifier("bookDao") // 要让首选装配起效果,@Qualifier自然就不能用了// @Autowired(required=false)// @Resource(name="bookDao2") @Inject private BookDao bookDao; public void print() {
System.out.println(bookDao); } @Override public String toString() {
return "BookService [bookDao=" + bookDao + "]"; } }

修改完毕后,我们运行IOCTest_Autowired类中的test01()方法,输出的结果信息如下所示。

在这里插入图片描述
可以看到,使用@Inject注解默认输出的是lable为2的bookDao。这是因为@Inject注解和@Autowired注解一样,默认优先装配使用了@Primary注解标注的组件。

其实,这也进一步说明了,@Inject注解和@Autowired注解的功能是一样的,都能实现自动装配,而且它俩都支持@Primary注解优先注入的功能。只不过,@Inject注解不能像@Autowired注解一样能添加required=false属性,因为它里面没啥属性。

@Resource和@Inject这俩注解与@Autowired注解的区别

不同点

  • @Autowired是Spring中的专有注解,而@Resource是Java中JSR250规范里面定义的一个注解,@Inject是Java中JSR330规范里面定义的一个注解
  • @Autowired支持参数required=false,而@Resource和@Inject都不支持
  • @Autowired和@Inject支持@Primary注解优先注入,而@Resource不支持
  • @Autowired通过@Qualifier指定注入特定bean,@Resource可以通过参数name指定注入bean,而@Inject需要通过@Named注解指定注入bean

相同点

三种注解都可以实现bean的自动装配。

转载地址:https://liayun.blog.csdn.net/article/details/110502633 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Spring注解驱动开发第22讲——如何实现方法、构造器位置的自动装配?我这样回答让面试官很满意!
下一篇:Spring注解驱动开发第20讲——使用@Autowired、@Qualifier、@Primary这三大注解自动装配组件,你会了吗?

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月14日 16时27分03秒