当前位置: 首页 > 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 技术来构建跨平台的移动应用。这种方式不仅能够提高开发效率,还能降低开发成…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...

大型活动交通拥堵治理的视觉算法应用

大型活动下智慧交通的视觉分析应用 一、背景与挑战 大型活动(如演唱会、马拉松赛事、高考中考等)期间,城市交通面临瞬时人流车流激增、传统摄像头模糊、交通拥堵识别滞后等问题。以演唱会为例,暖城商圈曾因观众集中离场导致周边…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

【Web 进阶篇】优雅的接口设计:统一响应、全局异常处理与参数校验

系列回顾: 在上一篇中,我们成功地为应用集成了数据库,并使用 Spring Data JPA 实现了基本的 CRUD API。我们的应用现在能“记忆”数据了!但是,如果你仔细审视那些 API,会发现它们还很“粗糙”:有…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...

Java入门学习详细版(一)

大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 在 GPU 上对图像执行 均值漂移滤波(Mean Shift Filtering),用于图像分割或平滑处理。 该函数将输入图像中的…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣(LeetCode) 思路 右视图是指从树的右侧看,对于每一层,只能看到该层最右边的节点。实现思路是: 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

AGain DB和倍数增益的关系

我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...