当前位置: 首页 > article >正文

注解 @Autowired 和 @Resource

文章目录

  • @Autowired 和 @Resource 的区别
    • 来源和规范
    • 装配方式
    • 支持的注入对象
    • 支持的参数
    • 可选性
    • 特定实现类
  • 使用 @Autowired 报错,而 @Resource 不会的情况
    • 存在多个匹配的 Bean。
    • PersonRepository Bean 是否正确配置:
    • 包扫描是否包含 PersonRepository:
    • 其他配置问题:

@Autowired 和 @Resource 的区别

来源和规范

  • @Autowired 是 Spring 框架提供的注解
  • @Resource 是 Java EE 规范提供的注解。在 Spring 中也可以使用,但它并不是 Spring 框架特有的注解,是Java定义的注解(JDK自带),它来自于JSR-250(Java 250 规范提案)。

装配方式

  • @Autowired注解是按照类型(byType)装配依赖对象。@Autowired 可以用在字段、构造函数、Setter 方法上,通过类型匹配进行自动装配。如果有多个匹配类型的 Bean,可以结合 @Qualifier 注解使用,或者通过 @Autowired(required = false) 配置为非必须的注入。
  • @Resource注解默认按照名称(byName)装配依赖对象。@Resource注解包含name和type两个属性,通过这两个属性,可以分别按照bean的名称和类型进行装配。如果没有指定name属性,那么默认会使用字段的名字进行名称匹配。同时,如果指定了name和type属性,Spring会从上下文中找到唯一匹配的bean进行装配。

支持的注入对象

  • @Autowired 主要用于注入 Spring 管理的 Bean,它是 Spring 框架的一部分。
  • @Resource 是 Java EE 规范的一部分,可以用于注入任何 Java 对象,不仅仅是 Spring 管理的 Bean。

支持的参数

  • @Autowired 主要有两个主要的参数:

    • required (boolean):默认值为 true,表示要求找到匹配的 Bean 进行注入。
      如果设置为 false,表示允许没有匹配的 Bean,即允许注入为 null。
    • qualifier (String):用于指定要注入的 Bean 的限定符(qualifier)。在一个容器中有多个相同类型的 Bean 时,可以使用 @Qualifier 注解进一步指定要注入的 Bean。示例:@Autowired @Qualifier("myBean")
  • @Resource 主要有两个参数:

    • name (String):用于指定要注入的 Bean 的名称。如果不指定,则默认按照属性名进行匹配。示例:@Resource(name = "myBean")
    • type (Class):用于指定要注入的 Bean 的类型。如果不指定,则按照属性的类型进行匹配。示例:@Resource(type = MyBean.class)

需要注意的是,@Resource 的 type 参数在 JDK 9 之后被废弃。因为 JDK 9 开始,@Autowired 已经变得更加灵活,可以替代大多数 @Resource 的用例。

可选性

  • @Autowired 是非常灵活的,但它在注入时必须能够找到匹配的 Bean,否则会抛出异常,除非使用 @Autowired(required = false) 设置为非必须的。
  • @Resource 可以设置 name 属性指定要注入的 Bean 的名称,但如果找不到匹配的 Bean,它会尝试按照类型进行注入。

特定实现类

  • @Autowired 是 Spring 特有的注解,因此在使用 @Autowired 时,你的代码与 Spring 框架耦合。
  • @Resource 是 Java EE 规范的一部分,可以在其他 Java EE 容器中使用。

在实际使用中,你可以根据具体的需求和场景选择使用 @Autowired 还是 @Resource。通常来说,@Autowired 更灵活,而 @Resource 更符合 Java EE 规范,可以提高代码的可移植性。

使用 @Autowired 报错,而 @Resource 不会的情况

如果使用 @Autowired 报错,可能是因为 Spring 框架没有找到可注入的 PersonRepository Bean。在这种情况下,可以尝试使用 @Resource 注解进行注入,或者检查以下几个可能的原因:

存在多个匹配的 Bean。

假设我们有以下代码:

@Service
class ServiceA {
    @Autowired
    private Dependency depA;
}

@Service
class ServiceB {
    @Autowired
    private Dependency depB;
}

@Service
class Dependency {}

@Service
class DependencyImpl extends Dependency {}

在这个例子中,ServiceA 和 ServiceB 都期望获得一个 Dependency 类型的依赖项。由于有两种类型的 Dependency Bean,Spring 不知道要使用哪一种,所以它将抛出异常。

如果你使用 @Resource 注解并提供具体的名称,Spring 就可以根据名称区分这两个 Bean:

@Service
class ServiceA {
    @Resource(name="depA")
    private Dependency depA;
}

@Service
class ServiceB {
    @Resource(name="depB")
    private Dependency depB;
}

@Service("depA")
class Dependency {}

@Service("depB")
class DependencyImpl extends Dependency {}

但如果没有显式地命名 Bean,则需要使用 @Qualifier 注解:

@Service
class ServiceA {
    @Autowired
    @Qualifier("depA")
    private Dependency depA;
}

@Service
class ServiceB {
    @Autowired
    @Qualifier("depB")
    private Dependency depB;
}

@Service("depA")
class Dependency {}

@Service("depB")
class DependencyImpl extends Dependency {}

请注意,即使你使用 @Resource 注解,如果不指定 name,它也会抛出异常。所以,如果你没有使用 @Qualifier 注解明确指出 Bean,@Autowired 也会抛出异常。

PersonRepository Bean 是否正确配置:

确保 PersonRepository 被正确配置为一个 Spring Bean。你可以在 PersonRepository 类上添加 @Repository 注解,以确保 Spring 能够扫描到并正确配置该 Bean。

@Repository
public interface PersonRepository extends Neo4jRepository<Person, Long> {
}

包扫描是否包含 PersonRepository:

确保 PersonRepository 所在的包在 Spring 的包扫描范围内。你可以在主程序入口类上添加 @SpringBootApplication 注解,这样 Spring 将会扫描该类所在的包以及子包。

@SpringBootApplication
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

其他配置问题:

检查是否有其他与 Bean 配置相关的问题,比如数据库连接等。如果上述方法都不起作用,你可以尝试手动创建 PersonRepository Bean。在你的配置类中添加如下代码:

@Configuration
public class AppConfig {

    @Bean
    public PersonRepository personRepository() {
        return new PersonRepositoryImpl(); // 请根据你的实际情况创建具体的 PersonRepository 实现类
    }
}

上述代码中的 PersonRepositoryImpl 应该是 PersonRepository 接口的一个实现类。这样,在 testController 中使用 @Autowired 注解就应该正常了。


http://www.kler.cn/news/161768.html

相关文章:

  • OpenGL ES 帧缓冲对象介绍和使用示例
  • AI烟火识别智能视频分析系统解决方案
  • Dockerfile详解#如何编写自己的Dockerfile
  • Matlab 用矩阵画图
  • JAVA 多线程并发(一)
  • Jmeter接口测试
  • STL(一)(pair篇)
  • 【Docker二】docker网络模式、网络通信、数据管理
  • Oracle11g RAC无法使用VIP或SCAN IP连接数据库的解决方案
  • 人工智能_机器学习061_KKT条件公式理解_原理深度解析_松弛变量_不等式约束---人工智能工作笔记0101
  • HTTP、HTTPS、SSL协议以及报文讲解
  • 【1day】DocCms 某接口SQL注入漏洞学习
  • Linux:缓冲区的概念理解
  • 什么是HTTPS加密协议? ️
  • Redission分布式锁原理初探
  • Docker架构及常用的命令
  • (五) Python 代理模式
  • 功能测试,接口测试,自动化测试,压力测试,性能测试,渗透测试,安全测试,具体是干嘛的?
  • 网站导航栏下滑隐藏,上滑显示,效果杠杆,兼容性强
  • node.js学习笔记——内部模块、自定义模块的导入和使用方式
  • 【Flink on k8s】- 12 - Flink kubernetes operator 的高级特性
  • 生成对抗网络GAN中的潜向量Z是用来做什么的?
  • Java 使用html2image将html生成缩略图图片
  • gcc安全特性之变量初始化检查
  • 二百一十、Hive——Flume采集的JSON数据文件写入Hive的ODS层表后字段的数据残缺
  • Python 适合做什么?
  • 关于popen执行命令无效,但是手动命令行执行有效的问题
  • redis查看统计信息
  • 智能优化算法应用:基于蛇优化算法无线传感器网络(WSN)覆盖优化 - 附代码
  • 题目:回文判定(蓝桥OJ 1371)