深入分析@Resource和@Autowired注解区别

 更新时间:2023年04月18日 16:42:20   作者:Cosolar  
这篇文章主要为大家介绍了深入分析@Resource和@Autowired注解区别,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

@Resource和@Autowired都是Spring Framework中用于依赖注入的注解,但它们有几点不同:

来源不同:@Resource注解来自于J2EE规范中;而@Autowired注解是Spring框架提供的。

搜索策略不同:@Resource注解默认按照名称进行匹配查找,如果找不到,则按照类型进行匹配。而@Autowired注解默认是按照类型进行匹配,如果出现多个类型一致的实例对象,则需要指定名称。

属性不同:@Resource注解没有属性名称,只有一个name属性,表示要注入的Bean名称。而@Autowired注解有两个重要属性:required和name,其中required属性表示是否必须注入该属性,默认为true;name属性表示要注入的Bean名称。

1、用法层面分析

首先,我们创建一个接口UserService和两个实现类UserServiceImpl1UserServiceImpl2

public interface UserService {
    void save();
}
@Service
public class UserServiceImpl1 implements UserService {
    @Override
    public void save() {
        System.out.println("UserServiceImpl1 save");
    }
}
@Service
public class UserServiceImpl2 implements UserService {
    @Override
    public void save() {
        System.out.println("UserServiceImpl2 save");
    }
}

然后,我们可以在需要使用UserService的地方进行依赖注入。

使用@Resource注解:

@Component
public class UserController {
    @Resource
    private UserService userService;
    // ...
}

使用@Autowired注解:

@Component
public class UserController {
    @Autowired(required = false)
    @Qualifier("userServiceImpl1")
    private UserService userService;
    // ...
}

上面的代码中,@Resource注解直接将UserService对象注入到userService属性中,而@Autowired注解需要结合@Qualifier注解来指定具体的Bean名称,并且通过required属性设置是否必须注入该属性。注意,@Autowired注解也可以省略@Qualifier注解,此时会按照类型进行匹配查找对应的Bean。

2、概念层面分析

再来分析一下其中的道道~~

Spring Framework中的依赖注入实现原理是基于Java反射机制和JavaBean规范的。

  • 通过反射机制实例化对象

Spring框架通过反射机制实例化需要注入的Bean对象,并将其存储到一个Map中,其中Key为Bean名称,Value为Bean实例对象。

  • 通过JavaBean规范完成Bean属性注入

接下来,Spring会根据JavaBean规范(即属性名以及该属性的setter方法)查找需要注入的属性,并通过反射机制调用对应的setter方法进行属性注入。

  • 依赖注入的搜索策略

在依赖注入的过程中,Spring框架通常采用两种搜索策略:

  • 按照类型搜索:当需要注入的属性的类型与容器中的多个Bean的类型一致时,会根据不同的注解选择不同的搜索策略。比如使用@Autowired注解时,默认按照类型匹配查找对应的Bean。
  • 按照名称搜索:当需要注入的属性的类型不唯一,或者需要注入的Bean名称与属性名称不一致时,可以使用@Qualifier注解指定要注入的Bean名称。
  • 使用各种注解进行依赖注入

Spring框架提供了多种注解用于依赖注入,包括:

  • @Autowired:按照类型进行注入;
  • @Resource:按照名称进行注入;
  • @Value:注入简单类型或字符串类型的属性;
  • @Inject:JSR-330标准定义的注解,功能与@Autowired类似。

Spring Framework的依赖注入实现原理是基于Java反射机制和JavaBean规范的,并通过多种注解实现不同的依赖注入方式。

@Resource和@Autowired都是Spring的依赖注入注解,但它们有如下区别:

  • 来源不同:@Resource是Java EE规范定义的注解,而@Autowired是Spring提供的注解。

  • 属性不同:@Resource注解没有required属性,只有name属性,表示要注入的Bean名称;而@Autowired注解有required和name属性,其中required表示是否必须注入该属性,默认为true;name表示要注入的Bean名称。

  • 查找方式不同:@Resource注解默认是根据byName的方式进行查找,如果找不到则按照byType进行查找;而@Autowired默认是根据byType方式进行查找。

  • 兼容性不同:@Resource注解可以与JSR-330的@Inject注解搭配使用;而@Autowired注解只能与Spring组件一起使用。

  • 应用场景不同:@Resource注解主要应用于Java EE环境,而@Autowired注解则是在Spring框架中使用最广泛的依赖注入注解之一,可以适用于不同的应用场景。

下面分别介绍@Resource和@Autowired注解的优缺点:

@Resource优点:

  • 简单易用,在类中使用非常方便。

  • 可以和@Inject注解一起使用。

  • 支持指定Bean名称,可以更精确地进行依赖注入。

@Resource缺点:

  • Spring框架对@Resource注解的支持不如@Autowired丰富。

  • 仅支持byName和byType两种注入方式,比@Autowired的支持更为有限。

@Autowired优点:

  • 支持复杂的依赖注入配置,可以通过多种方式进行依赖注入。

  • Spring框架对@Autowired注解的支持非常丰富,是Spring中使用最广泛的注解之一。

  • 可以指定是否必须注入该属性,也可以指定Bean名称进行注入。

  • 除了在类中使用之外,还可以在构造方法、Setter方法及任何标记了@Bean的方法中使用@Autowired注解。

@Autowired缺点:

  • 配置较为繁琐,需要指定required和name属性等。

  • 需要遵循Spring的自动扫描机制,只有标记了@Component、@Service、@Controller和@Repository等注解的类才会被Spring容器进行管理。

对于依赖注入的原理,可以简单地概括为以下三个步骤:

  • 在应用程序启动时,Spring容器负责创建和管理所有的Bean实例对象。

  • 在需要使用某个Bean的时候,Spring容器会通过反射机制将该Bean注入到需要使用的类或对象中。

  • 在Bean注入的过程中,Spring容器会根据不同的注解(如@Resource、@Autowired)采用不同的依赖注入方式,完成依赖注入的过程。

@Resouce和@Autowired都是Spring提供的依赖注入注解,各有优缺点。在实际开发中,可以根据具体的应用场景选择合适的注解进行使用。

3、源码层面分析

在Spring Framework源码层面,@Resource和@Autowired注解的实现类分别为javax.annotation.Resource和org.springframework.beans.factory.annotation.Autowired。下面我们来看一下它们的具体实现。

@Resource注解的实现原理:

  • 如果@Resource注解的name属性不为空,则Spring容器根据该属性值查找需要注入的Bean实例对象;如果name属性为空,则默认使用字段名作为Bean名称进行查找。
  • Spring容器会先根据byName注入方式进行查找,如果没有找到对应的Bean实例,则根据byType方式进行查找。
  • 如果找到了对应的Bean实例,则使用反射机制将该Bean实例注入到需要使用该实例的类或对象中。
  • 如果没有找到对应的Bean实例,则抛出NoSuchBeanDefinitionException异常。

代码示例:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
    String name() default "";
    Class<?> type() default java.lang.Object.class;
    boolean shareable() default true;
}

@Autowired注解的实现原理:

  • Spring容器会根据AutowiredAnnotationBeanPostProcessor类和AutowiredAnnotationBeanPostProcessor类的派生类进行处理,将使用@Autowired注解标记的所有属性注入到需要使用的类或对象中。
  • 对于AutowiredAnnotationBeanPostProcessor,其实现了BeanPostProcessor接口,在Bean实例化、初始化的过程中会拦截@Autowired注解。
  • 当Spring容器遇到@Autowired注解时,会自动调用AutowiredAnnotationBeanPostProcessor类的postProcessPropertyValues方法,该方法会根据不同的注解属性值进行不同的依赖注入处理。
  • 在处理@Autowired注解时,Spring容器默认使用byType的方式进行查找,如果存在多个匹配类型的Bean,则根据类名进行匹配;如果仍然无法确定注入哪个Bean,则抛出NoSuchBeanDefinitionException异常。

代码示例:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
    String value() default "";
}

无论是@Resource注解还是@Autowired注解,在Spring Framework源码实现上都是通过反射机制和BeanPostProcessor接口完成依赖注入的。在实际开发中,我们可以研究对应的源码实现,深入了解它们的原理,从而更好地使用这些依赖注入注解。

以上就是深入分析@Resource和@Autowired注解区别的详细内容,更多关于@Resource @Autowired注解区别的资料请关注脚本之家其它相关文章!

相关文章

  • Java数据结构与算法之树(动力节点java学院整理)

    Java数据结构与算法之树(动力节点java学院整理)

    这篇文章主要介绍了Java数据结构与算法之树的相关知识,最主要的是二叉树中的二叉搜索树,需要的朋友可以参考下
    2017-04-04
  • Swift洗牌动画效果的实现方法

    Swift洗牌动画效果的实现方法

    这篇文章主要介绍了Swift洗牌动画效果的实现方法,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2016-12-12
  • 详解springboot设置cors跨域请求的两种方式

    详解springboot设置cors跨域请求的两种方式

    这篇文章主要介绍了详解springboot设置cors跨域请求的两种方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Java图像处理之获取用户感兴趣的区域

    Java图像处理之获取用户感兴趣的区域

    OpenCV(Open Source Computer Vision Library)是一个开源的计算机视觉库,它提供了很多函数,这些函数非常高效地实现了计算机视觉算法。本文将利用OpenCV实现获取用户感兴趣的区域,从而达到抠图效果
    2022-07-07
  • Java精品项目瑞吉外卖之员工信息管理篇

    Java精品项目瑞吉外卖之员工信息管理篇

    这篇文章主要为大家详细介绍了java精品项目-瑞吉外卖订餐系统,此项目过大,分为多章独立讲解,本篇内容为员工信息分页查询与启用或禁用员工状态,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • SpringBoot 利用MultipartFile上传本地图片生成图片链接的实现方法

    SpringBoot 利用MultipartFile上传本地图片生成图片链接的实现方法

    这篇文章主要介绍了SpringBoot 利用MultipartFile上传本地图片生成图片链接的实现方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • Java 实战项目锤炼之IT设备固定资产管理系统的实现流程

    Java 实战项目锤炼之IT设备固定资产管理系统的实现流程

    读万卷书不如行万里路,只学书上的理论是远远不够的,只有在实战中才能获得能力的提升,本篇文章手把手带你用Java+SSM+jsp+mysql+maven实现一个IT设备固定资产管理系统,大家可以在过程中查缺补漏,提升水平
    2021-11-11
  • Java集合类中文介绍

    Java集合类中文介绍

    本文首先对Java集合类框架做了简单说明,之后对主要类和为API做了介绍:Collection、List、Set、AbstractCollection、AbstractList、AbstractSet、Iterator、ListIterator。
    2013-11-11
  • 解决JMap抓取heap使用统计信息报错的问题

    解决JMap抓取heap使用统计信息报错的问题

    这篇文章主要介绍了解决JMap抓取heap使用统计信息报错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • RocketMQ事务消息机制详解

    RocketMQ事务消息机制详解

    这篇文章主要介绍了RocketMQ事务消息机制详解,RocketMQ服务端将消息持久化之后,向发送方返回Ack确认消息已经发送成功,由于消息为半事务消息,在未收到生产者对该消息的二次确认前,此消息被标记成"暂不能投递"状态,需要的朋友可以参考下
    2024-01-01

最新评论