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

@AutoWired和 @Resource原理深度分析!

嗨,你好呀,我是猿java

@Autowired@Resource是 Java程序员经常用来实现依赖注入的两个注解,这篇文章,我们将详细分析这两个注解的工作原理、使用示例和它们之间的对比。

依赖注入概述

依赖注入是一种常见的设计模式,用于实现控制反转(Inversion of Control, IoC)。在传统的编程中,类通常负责管理自己的依赖,而在 DI中,这种责任被转移到了外部容器(如 Spring容器)上,通过 DI,可以提高代码的可测试性和可维护性,因为依赖关系是通过配置而不是硬编码的。

@Autowired

@Autowired是 Spring框架提供的注解,用于自动装配 bean。它可以用在构造器、方法、字段或参数上,Spring容器会通过类型匹配(byType)来注入依赖。

@Autowired的工作原理

  • 类型匹配:Spring首先通过类型匹配来查找合适的bean。如果找到一个唯一的bean,则注入该bean。
  • 候选Bean的歧义:如果有多个同类型的bean,Spring会通过字段名或参数名来进一步匹配。
  • @Primary注解:可以使用@Primary注解来标记一个bean为主要候选者。
  • @Qualifier注解:在多个候选bean的情况下,可以使用@Qualifier注解来指定注入的bean。

作用范围

@Autowired的作用范围包括三种:

  • 字段注入:最简单的方式,但不利于单元测试,因为依赖是通过反射注入的。
  • 构造器注入:推荐的方式,因为它可以确保依赖在对象创建时就被注入。
  • 方法注入:通过一个setter方法注入依赖。

在Spring框架中,依赖注入可以通过多种方式来实现,主要包括构造器注入、字段注入和方法注入。每种方式都有其特定的使用场景和优缺点。下面我将为每种注入方式提供示例代码,以帮助理解其实现和适用场景。

字段注入

字段注入是通过直接在类的字段上使用注解来实现的,这种方式最为简单,但也有一些缺点,特别是在单元测试中,因为它依赖于反射来设置字段的值。Spring官方已经不建议这种使用方式。

如下示例展示了字段注入:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class CarService {@Autowiredprivate Engine engine;public void start() {engine.run();}
}@Component
public class Engine {public void run() {System.out.println("Engine is running");}
}
适用场景
  • 快速原型:在快速开发或原型阶段,字段注入可以减少样板代码。
  • 简单的依赖关系:如果类的依赖关系简单且不需要复杂的初始化逻辑,字段注入可以提供一种直接的方式。
缺点
  • 测试困难:由于字段是私有的,单元测试时需要使用反射来设置字段的值,这增加了复杂性。
  • 不支持final字段:因为字段注入发生在对象实例化之后,无法用于final字段。

构造器注入

构造器注入是通过类的构造函数来实现依赖注入的,这种方式被广泛推荐,因为它可以在对象创建时确保所有依赖都被正确注入,从而避免未初始化的依赖。

如下示例展示了构造器注入:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class CarService {private final Engine engine;@Autowired  // 可以省略,因为只有一个构造函数时,Spring会自动注入public CarService(Engine engine) {this.engine = engine;}public void start() {engine.run();}
}@Component
public class Engine {public void run() {System.out.println("Engine is running");}
}
适用场景
  • 不可变性:如果你希望你的类是不可变的,构造器注入是最佳选择,因为它可以确保所有依赖在对象创建时都被注入。
  • 必需依赖:如果某个依赖是必需的,构造器注入可以确保在对象创建时注入该依赖。

方法注入

方法注入(通常是 setter方法注入)是通过提供一个公共的 setter方法来实现的。这种方式提供了一种在对象实例化后设置依赖的灵活性。

如下示例展示了方法注入:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class CarService {private Engine engine;@Autowiredpublic void setEngine(Engine engine) {this.engine = engine;}public void start() {engine.run();}
}@Component
public class Engine {public void run() {System.out.println("Engine is running");}
}
适用场景
  • 可选依赖:如果某个依赖是可选的,方法注入可以让你在必要时设置该依赖。
  • 需要后期配置:如果需要在对象实例化后进行额外的配置或初始化,方法注入提供了一种灵活的方式。

@Resource

@Resource是Java EE(Jakarta EE)提供的注解,用于注入依赖,它可以用在字段或setter方法上,主要通过名称匹配来注入依赖。

@Resource的工作原理

  • 名称匹配@Resource首先通过名称匹配来查找bean。如果名称匹配失败,则通过类型匹配。
  • 简单配置@Resource不支持复杂的注入配置,如@Qualifier

@Resource使用示例

import javax.annotation.Resource;
import javax.ejb.Stateless;@Stateless
public class CarService {@Resourceprivate Engine engine;// 其他方法
}public class Engine {// Engine的实现
}

在这个示例中,CarService使用@Resource注解来注入Engine对象。

@Autowired@Resource的对比

提供者

  • @Resource是Java EE规范的一部分,适用于任何兼容的Java EE容器。
    • @Autowired是Spring框架提供的注解,需要依赖 Spring框架,同时也支持@Resource

匹配策略

  • @Autowired主要通过类型匹配,必要时通过@Qualifier进一步指定。
  • @Resource主要通过名称匹配,然后才是类型匹配。

配置复杂度

  • @Autowired支持更多的配置选项,如@Primary@Qualifier
  • @Resource配置相对简单,不支持复杂配置。

框架依赖

  • @Autowired是Spring特有的注解,需要依赖Spring框架。
  • @Resource是Java EE规范的一部分,适用于任何兼容的Java EE容器。

使用场景

  • 如果使用 Spring框架,@Autowired是更常用的选择,因为它提供了更多功能。
  • 在Java EE环境中,@Resource是标准的选择。

总结

@Autowired@Resource是 Java开发中实现依赖注入的两种常用方式。虽然它们都可以用于自动装配 bean,但在匹配策略、配置复杂度和框架依赖上存在显著差异。因此,理解两者的原理和差异,可以帮助我们更好地理解 Java依赖注入的机制,更好的应用这两个注解。

交流学习

最后,把猿哥的座右铭送给你:投资自己才是最大的财富。 如果你觉得文章有帮助,请帮忙转发给更多的好友,或关注:猿java,持续输出硬核文章。

相关文章:

@AutoWired和 @Resource原理深度分析!

嗨,你好呀,我是猿java Autowired和Resource是 Java程序员经常用来实现依赖注入的两个注解,这篇文章,我们将详细分析这两个注解的工作原理、使用示例和它们之间的对比。 依赖注入概述 依赖注入是一种常见的设计模式,…...

C++设计模式创建型模式———原型模式

文章目录 一、引言二、原型模式三、总结 一、引言 与工厂模式相同,原型模式(Prototype)也是创建型模式。原型模式通过一个对象(原型对象)克隆出多个一模一样的对象。实际上,该模式与其说是一种设计模式&am…...

重学SpringBoot3-Spring WebFlux之SSE服务器发送事件

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ Spring WebFlux之SSE服务器发送事件 1. 什么是 SSE?2. Spring Boot 3 响应式编程与 SSE为什么选择响应式编程实现 SSE? 3. 实现 SSE 的基本步骤3.…...

YOLO即插即用模块---AgentAttention

Agent Attention: On the Integration of Softmax and Linear Attention 论文地址:https://arxiv.org/pdf/2312.08874 问题: 普遍使用的 Softmax 注意力机制在视觉 Transformer 模型中计算复杂度过高,限制了其在各种场景中的应用。 方法&a…...

探索开源语音识别的未来:高效利用先进的自动语音识别技术20241030

🚀 探索开源语音识别的未来:高效利用自动语音识别技术 🌟 引言 在数字化时代,语音识别技术正在引领人机交互的新潮流,为各行业带来了颠覆性的改变。开源的自动语音识别(ASR)系统,如…...

学习路之TP6--workman安装

一、安装 首先通过 composer 安装 composer require topthink/think-worker 报错: 分析:最新版本需要TP8,或装低版本的 composer require topthink/think-worker:^3.*安装后, 增加目录 vendor\workerman vendor\topthink\think-w…...

.NET内网实战:通过白名单文件反序列化漏洞绕过UAC

01阅读须知 此文所节选自小报童《.NET 内网实战攻防》专栏,主要内容有.NET在各个内网渗透阶段与Windows系统交互的方式和技巧,对内网和后渗透感兴趣的朋友们可以订阅该电子报刊,解锁更多的报刊内容。 02基本介绍 03原理分析 在渗透测试和红…...

AI Agents - 自动化项目:计划、评估和分配

Agents: Role 角色Goal 目标Backstory 背景故事 Tasks: Description 描述Expected Output 期望输出Agent 代理 Automated Project: Planning, Estimation, and Allocation Initial Imports 1.本地文件helper.py # Add your utilities or helper functions to…...

Git的.gitignore文件

一、各语言对应的.gitignore模板文件 项目地址:https://github.com/github/gitignore 二、.gitignore文件不生效 .gitignore文件只是ignore没有被追踪的文件,已被追踪的文件,要先删除缓存文件。 # 单个文件 git rm --cached file/path/to…...

网站安全,WAF网站保护暴力破解

雷池的核心功能 通过过滤和监控 Web 应用与互联网之间的 HTTP 流量,功能包括: SQL 注入保护:防止恶意 SQL 代码的注入,保护网站数据安全。跨站脚本攻击 (XSS):阻止攻击者在用户浏览器中执行恶意脚本。暴力破解防护&a…...

深度学习:梯度下降算法简介

梯度下降算法简介 梯度下降算法 我们思考这样一个问题,现在需要用一条直线来回归拟合这三个点,直线的方程是 y w ^ x b y \hat{w}x b yw^xb,我们假设斜率 w ^ \hat{w} w^是已知的,现在想要找到一个最好的截距 b b b。 一条…...

SparkSQL整合Hive后,如何启动hiveserver2服务

当spark sql与hive整合后,我们就无法启动hiveserver2的服务了,每次都要先启动hive的元数据服务(nohup hive --service metastore)才能启动hive,之前的beeline命令也用不了,hiveserver2的无法启动,这也导致我…...

前端路由如何从0开始配置?vue-router 的使用

在 Web 开发中,路由是指根据 URL 的不同部分将请求分发到不同的处理函数或页面的过程。路由是单页应用(SPA, Single Page Application)和服务器端渲染(SSR, Server-Side Rendering)应用中的一个重要概念。 在开发中如何…...

Java中的运算符【与C语言的区别】

目录 1. 算术运算符 1.0 赋值运算符: 1.1 四则运算符: - * / % 【取余与C有点不同】 1.2 增量运算符: - * / % * 【右侧运算结果会自动转换类型】 1.3 自增、自减:、-- 2. 关系运算符 3. 逻辑运算符 3.1 短路求值 3.2 【…...

二、基础语法

入门了解 注释 **作用:**在代码中加一些注释和说明,方便自己或者其他程序员阅读代码 两种格式: 单行注释:// 描述信息 通常放在一行代码的上方,或者一条语句的末尾,对该行代码进行说明 多行注释&#x…...

DB-GPT系列(一):DB-GPT能帮你做什么?

DB-GPT是一个开源的AI原生数据应用开发框架(AI Native Data App Development framework with AWEL and Agents),围绕大模型提供灵活、可拓展的AI原生数据应用管理与开发能力,可以帮助企业快速构建、部署智能AI数据应用,通过智能数据分析、洞察…...

【Python各个击破】numpy

简介 NumPy是一个开源的Python库,它提供了一个强大的N维数组对象和许多用于操作这些数组的函数。它是大多数Python科学计算的基础,包括Pandas、SciPy和scikit-learn等库都建立在NumPy之上。 安装 !pip install numpy导入 import numpy as np用法 # …...

【STM32 Blue Pill编程实例】-4位7段数码管使用

4位7段数码管使用 文章目录 4位7段数码管使用1、7段数码介绍2、硬件准备与接线3、模块配置4、代码实现在本文中,我们将介绍如何将 STM32 Blue Pill开发板与 4 位 7 段数码管连接,并在 STM32CubeIDE 中对其进行编程。 在文章中首先将介绍 4 位 7 段数码管及其与 STM32 Blue Pi…...

[进阶]java基础之集合(三)数据结构

文章目录 数据结构概述常见的数据结构数据结构(栈)数据结构(队列)数据结构(数组)数据结构(链表) 数据结构 概述 数据结构是计算机底层存储、组织数据的方式。是指数据相互之间是以什么方式排列在一起的。数据结构是为了更加方便的管理和使用数据,需要结合具体的业…...

《Apache Cordova/PhoneGap 使用技巧分享》

一、引言 在移动应用开发的领域中,Apache Cordova(也被称为 PhoneGap)是一个强大的工具,它允许开发者使用 HTML、CSS 和 JavaScript 等 Web 技术来构建跨平台的移动应用。这种方式不仅能够提高开发效率,还能降低开发成…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

C++ 基础特性深度解析

目录 引言 一、命名空间(namespace) C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用(reference)​ C 中的引用​ 与 C 语言的对比​ 四、inline(内联函数…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南

1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习)

Aspose.PDF 限制绕过方案:Java 字节码技术实战分享(仅供学习) 一、Aspose.PDF 简介二、说明(⚠️仅供学习与研究使用)三、技术流程总览四、准备工作1. 下载 Jar 包2. Maven 项目依赖配置 五、字节码修改实现代码&#…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...