【Springboot】@Autowired和@Resource的区别

【Springboot】@Autowired和@Resource的区别

【一】定义

@Resource 和@Autowired 这两个注解的作用都是在Spring 生态里面去实现Bean 的依赖注入。

【1】@Autowired

对类成员变量、方法和构造函数进行标注,完成自动装配的工作

【2】@Resource

在语义上被定义为通过唯一的名称来标识特定的目标组件,其中声明的类型与匹配过程无关

【二】区别

在spring框架中,如果在service层需要注入其他依赖的对象,通常我们都会使用@Autowired或者@Resource注解。@Autowired跟Spring框架强耦合了,如果换成其他的框架,@Autowired就没有作用了,而@Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持

【1】包含的属性不同

(1)@Autowired只包含一个参数:required,表示是否开启自动注入,默认是true。

(2)@Resource包含七个参数:其中最重要的两个参数是:name和type。

java 复制代码
public @interface Autowired {
  //是否开启自动注入,有些时候我们不想使用自动装配功能,可以将该参数设置成false。
	boolean required() default true;
}
 
 
public @interface Resource {
		//bean的名称
    String name() default "";
 
    String lookup() default "";
 		//Java类,被解析为bean的类型
    Class<?> type() default java.lang.Object.class;
 
    enum AuthenticationType {
            CONTAINER,
            APPLICATION
    }
 
    // 身份验证类型
    AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
    //组件是否可以与其他组件之间共享
    boolean shareable() default true;
    String mappedName() default "";
    //描述
    String description() default "";
}

【2】@Autowired默认按byType自动装配,而@Resource默认byName自动装配

@Autowired如果要使用byName,需要使用@Qualifier一起配合,而@Resource如果指定了name,则用byName自动装配,如果指定了type,则用byType自动装配

【3】注解应用的地方不同

@Autowired能够用在:构造器、方法、参数、成员变量和注解上,二@Resource能用在:类、成员变量、方法上

【4】出处不同

@Autowired是Spring定义的注解,而@Resource是JSR-250定义的注解,所以@Autowired只能在spring框架下使用,而@Resource则可以和其他框架一起使用

【5】装配顺序不用

(1)@Autowired的装配顺序如下

@Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如果还有多个,则报出异常。

(2)@Resource的装配顺序如下

(1)如果同时指定了name和type,流程如下:

(2)如果指定了name,流程如下:

只是指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean。

(3)如果指定了type,流程如下:

只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。

(4)如果既没有指定name,也没有指定type,流程如下:

既不指定name属性,也不指定type属性,则自动按byName方式进行查找。如果没有找到符合的bean,则回退为一个原始类型进行进行查找,如果找到就注入。

【三】@Autowired使用案例

(1)参数

@Autowired 注解里面有一个 required 属性默认值是 true,表示强制要求bean实例的注入, 在应用启动的时候,如果 IOC 容器里面不存在对应类型的Bean,就会报错。当然,如果不希望自动注入,可以把这个属性设置成 false。

(2)取bean逻辑

如果在容器中有多个相同类型的Bean,使用@Autowired注入Bean,则去找名称和注入属性的属性名相同的Bean,如果能找到唯一的,则注入成功,否则应用启动的时候就会报错,大概意思是指注入只需要一个Bean实例,但在容器中找到了多个(容器不知道该注入那个Bean)。为了解决问题,需要配合@Qualifier注解使用。@Qualifier注解可以从多个相同类型的Bean里筛选出一个Bean名称和@Qualifier注解的value属性相同的Bean。如果容器中恰好找到一个这样的Bean,则应用启动的时候成功注入这个Bean实例。同样的,当有多个同类型的Bean时,@Parimary标注的Bean作为主要的Bean会被优先注入。

(3)只使用@Autowired注解,InjectTestController注入InjectTestService

java 复制代码
/* InjectTestController注入InjectTestService,此时容器中
有两个InjectTestService类型的Bean(injectTestService,injectTestServiceImpl)。
因为注入属性的属性名为injectTestService,
容器中恰好存在一个名称为injectTestService的Bean,
所以名称为injectTestService的Bean可以成功注入到属性injectTestService,
应用启动不报错。*/
 
@Controller
public class InjectTestController {
    @Autowired
    private InjectTestService injectTestService;
}
 
@Configuration
public class BeanConfig {
   @Bean
   public InjectTestService injectTestService(){
       return new InjectTestServiceImpl();
   }
}
 
@Service
public class InjectTestServiceImpl implements InjectTestService {
}

(4)@Autowired注解和@Qualifier注解配合使用,InjectTestController注入InjectTestService

java 复制代码
/* 容器中存在两个类型为InjectTestService的Bean(injectTestService,injectTestServiceImpl),
但经过@Qualifier的value属性筛选,找到了名称为injectTestServiceImpl的Bean,
因此可以成功注入到属性service中 */
 
 
@Controller
public class InjectTestController {
    @Autowired
    @Qualifier("injectTestServiceImpl")
    private InjectTestService service;
}
 
@Configuration
public class BeanConfig {
   @Bean
   public InjectTestService injectTestService(){
       return new InjectTestServiceImpl();
   }
}
 
@Service
public class InjectTestServiceImpl implements InjectTestService {
}

(5)@Autowired注解和@Primary注解配合使用,InjectTestController注入InjectTestService

java 复制代码
/* 容器中存在两个类型为InjectTestService的Bean(injectTestService,injectTestServiceImpl),
但@Primary注解指定名称为injectTestService的Bean为主Bean,在多个同类型的Bean的时候会优先注入
因此可以成功注入到属性service中 */
 
 
@Controller
public class InjectTestController {
    @Autowired
    private InjectTestService service;
}
 
@Configuration
public class BeanConfig {
   @Bean
   @Primary
   public InjectTestService injectTestService(){
       return new InjectTestServiceImpl();
   }
}
 
@Service
public class InjectTestServiceImpl implements InjectTestService {
}

(6)@Resource

@Resource 是 JDK 提供的注解,只是 Spring 在实现上提供了这个注解的功能支持。 它的使用方式和@Autowired 完全相同,最大的差异于@Resource 可以支持ByName 和 ByType 两种注入方式。 如果使用name,Spring就根据bean的名字实现依赖注入,如果使用type,Spring就根据类型实现依赖注入。 如果两个属性都没配置,就先根据定义的属性名字去匹配,如果没匹配成功,再根据类型匹配。两个都没匹配到,就报错。

相关推荐
用户345848285053 分钟前
java中的tomicInteger/AtomicLong介绍
前端·后端
jiayong235 分钟前
Elasticsearch Java 开发完全指南
java·大数据·elasticsearch
一颗宁檬不酸5 分钟前
Vue.js 初学者基础知识点总结 第一弹
前端·javascript·vue.js
321茄子6 分钟前
MySQL 事务隔离性及锁
java·数据库·mysql
xiaoxue..7 分钟前
解析 LocalStorage与事件委托在前端数据持久化中的应用
前端·javascript·面试
Mintopia7 分钟前
「无界」全局浮窗组件设计与父子组件最佳实践
前端·前端框架·前端工程化
杀死那个蝈坦9 分钟前
UV 统计(独立访客统计)
java·jvm·spring·kafka·tomcat·maven
带刺的坐椅11 分钟前
Solon AI 开发学习7 - chat - 四种消息类型及提示语增强
java·ai·llm·solon
济宁雪人12 分钟前
Java安全基础——序列化/反序列化
java·开发语言
1***Q78412 分钟前
后端在微服务中的服务路由
java·数据库·微服务