Spring framework Day10:JSR330注入注解
前言
JSR330是Java社区标准化进程(Java Community Process,简称JCP)中的一个规范,全名为"Dependency Injection for Java",即Java的依赖注入规范。它定义了一组注解和相关的规范,用于实现依赖注入(Dependency Injection,简称DI)。
依赖注入是一种设计模式,旨在解耦应用程序中的不同模块或组件之间的依赖关系。通过依赖注入,可以将对象的创建、维护和配置等责任从使用对象的代码中剥离出来,并由容器负责提供和注入所需的依赖项。
一、开始学习
本次主学习三个注解,@RequiredArgsConstructor、@Inject、@Named。那么它们分别是什么意思,有什么用呢?
@RequiredArgsConstructor、@Inject和@Named是JSR330规范中的注解,用于实现依赖注入。
@RequiredArgsConstructor:这是一个Lombok注解,而不是JSR330规范中的注解。它可以用于生成一个包含所有标记为final或@NonNull的字段的构造函数。这样,在使用@RequiredArgsConstructor注解的类中,就无需手动编写构造函数,Lombok会自动帮我们生成。这在依赖注入中特别有用,可以省去手动编写大量的构造函数代码。
@Inject:这是JSR330规范中的注解,用于标记需要进行依赖注入的构造方法、字段或者方法。通过在目标类中标记@Inject,依赖注入框架会在需要的时候自动实例化并注入相应的依赖项。
@Named:也是JSR330规范中的注解,用于为依赖项指定名称或者限定符。当一个接口有多个实现类时,可以通过@Named注解配合不同的名称来区分注入的具体实例。在使用@Inject进行注入时,可以结合@Named注解指定要注入的具体实现。
这些注解都是为了简化依赖注入的使用,并保持与JSR330规范的一致性。通过标记相关的注解,我们可以更方便地使用依赖注入框架来管理和注入各个组件的依赖关系。
1、新建项目,结构如下

2、导入 spring 依赖
<!-- spring 的核心依赖 --><dependencies><!-- https://mvnrepository.com/artifact/org.springframework/spring-context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.23</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.4.5</version></dependency><!-- JSR 330 标准注入注解 --><dependency><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><version>1</version></dependency></dependencies>
注意:@Inject 不存在 JDK 11 中,如果要使用需要额外添加依赖,我使用的是 JDK 11,所以需要自己添加依赖使用 @Inject 注解。
3、在 service 包下新建一个 UserService 接口,在 impl 包下新建一个 UserServiceImpl 实现类
UserService 接口
public interface UserService {void save();
}
UserServiceImpl 实现类
@Slf4j
@Service("userService")
public class UserServiceImpl implements UserService {@Overridepublic void save() {log.info("添加用户.....");}
}
4、在 controller 包下新建 UserController 类,使用 @RequiredArgsConstructor 注解
@Controller
@RequiredArgsConstructor
public class UserController {private final UserService userService;public void addUser() {userService.save();}}
这是一个示例的Java类,使用了Spring框架中的注解来实现依赖注入和控制反转(IoC)。
在这个示例中,
UserController是一个控制器类,使用了@Controller注解来标识它是一个控制器组件。@RequiredArgsConstructor注解是Lombok库提供的,用来自动生成构造函数并注入依赖。
UserController类有一个私有字段userService,通过final关键字标记,并在构造函数中进行初始化。这里使用了构造函数注入,即通过构造函数将UserService的实例注入到UserController中,实现了依赖注入。在
addUser方法中,调用了userService.save()方法。由于userService字段已经通过必要的构造函数注入,因此可以直接使用userService对象调用其中的方法。整体而言,这段代码展示了基于Spring框架的控制器类定义和依赖注入的方式。通过使用相应的注解,可以方便地管理和注入依赖对象,实现松耦合的组件之间的协作。
lombook 迎合了 spring 4.2 的新特性实现了更加简洁的注入方式,使用 @RequiredArgsConstructor 注解,lombook 会自动添加一个带参的构造方法实现构造器的注入,注意;此时的字段必须是final 修饰
5、在 resources 下新建一个 spring 的 xml 文件 application.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><!-- 启用包扫描 --><context:component-scan base-package="edu.nf.ch09"/></beans>
6、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserController bean = context.getBean(UserController.class);bean.addUser();}}
运行结果

二、使用 @inject、@Named 注解
1、在 service 包下的 impl 包下在新建一个 StuServiceImpl 实现类
@Slf4j
@Service("stuService")
public class StuServiceImpl implements UserService {@Overridepublic void save() {log.info("添加学生......");}
}
2、使用 setter 方法注入
@Controller
public class UserController {private final UserService userService;/*** 当有多个实现类,并且方法参数与 id 不一致时,* 可以结合 @Named 注解来指定 bean 的 id 又或者* 可以使用 @Primary 注解设置注入的优先级** @param aa*/@Inject@Named("userService")public UserController(UserService aa) {this.userService = aa;}public void addUser() {userService.save();}}
上述代码是一个使用了
@Inject和@Named注解进行依赖注入的示例,涉及到多个实现类时可以使用@Named注解来指定要注入的实现类的bean的id。
@Inject是Java依赖注入规范中定义的注解,用于在运行时自动注入需要的实例。在使用@Inject注解时,可以结合使用@Named注解来指定要注入的实例的bean的id,这样Spring框架就可以根据指定的bean id来选择对应的实例进行注入。在上面的示例中,
UserController类被标记为@Controller组件,用于处理HTTP请求。UserService字段被声明为final,并在构造函数中通过@Inject和@Named注解进行注入。使用@Named("userService")可以指定要注入的bean为id为"userServie"的bean。在addUser()方法中,直接调用userService.save()方法即可使用该对象提供的服务。整体来说,使用注解进行依赖注入的好处是可以避免手动管理对象依赖关系,从而减少与依赖相关的代码量和复杂度,并且避免由于错误的依赖关系引起的运行时异常。
3、测试
public class Main {public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");UserController bean = context.getBean(UserController.class);bean.addUser();}}
运行结果

那如果要调用 StudentServiceImpl 实现类的方法呢?很简单,只需要把 @Named 的值改为注入的bean为id为"stuService"的bean 即可。
三、使用 @RequiredArgsConstructor、@Inject、@Named 有什么好处
@RequiredArgsConstructor、@Inject和@Named这些注解在依赖注入中可以提供以下好处:
@RequiredArgsConstructor注解:该注解是Lombok库提供的注解,用于自动生成构造函数,其中参数为被声明为final或者被标记为@NonNull的字段。使用该注解可以简化代码,省略手动编写构造函数的过程,从而提高开发效率。
@Inject注解:该注解是Java依赖注入(JSR-330)规范中定义的注解,用于在运行时自动注入所需的实例。使用该注解可以避免手动处理对象的依赖关系,框架会自动将所需的实例注入到相应的位置。这样可以减少与依赖相关的代码量和复杂度,并且降低耦合度,使代码更加可维护和可测试。
@Named注解:该注解也是Java依赖注入(JSR-330)规范中定义的注解,用于为bean指定唯一的名称或id。当存在多个实现类时,可以使用@Named注解来标识不同的实现类,然后在注入时根据指定的bean名称进行选择注入哪个实例。使用@Named注解可以更精确地控制依赖注入的目标对象,提高灵活性。
综上所述,使用@RequiredArgsConstructor可以简化构造函数的编写,提高代码效率;@Inject可以自动注入依赖,减少手动管理对象依赖关系的代码量和复杂度;@Named可以为bean指定唯一的名称或id,使得在存在多个实现类时更精确地控制注入目标。这些注解能够有效地提高代码的可读性、可维护性和可测试性,同时减少出错的可能性。
四、gitee 案例
案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git
相关文章:
Spring framework Day10:JSR330注入注解
前言 JSR330是Java社区标准化进程(Java Community Process,简称JCP)中的一个规范,全名为"Dependency Injection for Java",即Java的依赖注入规范。它定义了一组注解和相关的规范,用于实现依赖注…...
Java开发中List数据量大,需要分片批次处理
在开发过程中可能会遇到需要处理的List数据量过大,可以选择分批处理的方式对大量数据进行处理。 1、使用 apache 的工具包 <dependency><groupId>org.apache.commons</groupId><artifactId>commons-collections4</artifactId><v…...
Apache Doris 2.0.2 版本正式发布!
峰会官网已上线,最新议程请关注:doris-summit.org.cn 点击报名 亲爱的社区小伙伴们,Apache Doris 2.0.2 版本已于 2023 年 10 月 6 日正式发布,该版本对多个功能进行了更新优化,旨在更好地满足用户的需求。有 92 位贡献…...
transformers架构实现
目录 架构代码如下 模型打印如下 架构代码如下 import numpy as np from torch.autograd import Variable import copy from torch import softmax import math import torch import torch.nn.functional as F import torch.nn as nn # 构建Embedding类来实现文本嵌入层 class…...
C++类型推导
这里对C的类型推导方式进行一次全面的总结。 C中有三种类型推导的方式,分别是模板、auto以及decltype()。以下分别介绍这三种方式的同异。 一 模板 假设有这样的函数模板和这样的调用: template<typename T> void f(ParamType param);f(expr);…...
Open3D(C++) SVD分解求两个点云的变换矩阵
目录 一、算法原理二、代码实现三、结果展示四、相关链接一、算法原理 计算两个点云的质心计算中心化向量计算协方差矩阵奇异值分解,求解旋转矩阵 R R R计算平移向量 t t...
rtmp htttp推流Windows桌面到srs进行播放
推流命令: ffmpeg -f gdigrab -framerate 30 -i desktop -c:v libx264 -preset ultrafast -tune zerolatency -pix_fmt yuv420p -f flv rtmp://xxx.xxx.xxxx.xx/live/livestream 后面是推流地址 推流后的播放地址为: http://xxxxxx:8080/live/livestream.flv 可以写一个…...
NSSCTF做题(9)
[GDOUCTF 2023]<ez_ze> 看见输入框而且有提示说是ssti注入 输入{{7*7}} 试试,发现报错 输入{%%}发现了是jinja2模板 找到关键函数 Python SSTI利用jinja过滤器进行Bypass ph0ebuss Blog 原理见这篇文章,这里直接给出payload {%set ninedict(aaa…...
【09】基础知识:React组件的生命周期
组件从创建到死亡它会经历一些特定的阶段。 React 组件中包含一系列勾子函数(生命周期回调函数 <> 生命周期钩子函数 <> 生命周期函数 <> 生命周期钩子),会在特定的时刻调用。 我们在定义组件时,会在特定的生…...
Pytorch之ConvNeXt图像分类
文章目录 前言一、ConvNeXt设计决策1.设计方案2.Training Techniques3.Macro Design🥇Changing stage compute ratio🥈Change stem to "Patchify" 4.ResNeXt-ify5. Inverted Bottleneck6.Large Kernel Size7.Micro Design✨Replacing ReLU wit…...
Linux系统编程:makefile以及文件系统编程
增量编译概念 首先回顾一下我们之前写的各种gcc指令用来执行程序: 可以看见非常繁琐,两个文件就要写这么多,那要是成百上千岂不完蛋。 所以为了简化工作量,很自然的想到了将这些命令放在一起使用脚本文件来一键执行,…...
《动手学深度学习 Pytorch版》 8.5 循环神经网络的从零开始实现
%matplotlib inline import math import torch from torch import nn from torch.nn import functional as F from d2l import torch as d2lbatch_size, num_steps 32, 35 train_iter, vocab d2l.load_data_time_machine(batch_size, num_steps) # 仍然使用时间机器数据集8.…...
写一个宏,可以将一个整数的二进制位的奇数位和偶数位交换
我们这里是利用按位与来计算的 我们可以想想怎么保留偶数上的位?我们可以利用0x55555555按位与上这个数就保留了偶数 我们知道,16进制0x55555555转换为二进制就是0x01010101010101010101010101010101 我们知道,二进制每一位,如…...
Zabbix监控系统详解2:基于Proxy分布式实现Web应用监控及Zabbix 高可用集群的搭建
文章目录 1. zabbix-proxy的分布式监控的概述1.1 分布式监控的主要作用1.2 监控数据流向1.3 构成组件1.3.1 zabbix-server1.3.2 Database1.3.3 zabbix-proxy1.3.4 zabbix-agent1.3.5 web 界面 2. 部署zabbix代理服务器2.1 前置准备2.2 配置 zabbix 的下载源,安装 za…...
docker 安装oracle
拉取镜像 拉取oracle_11g镜像 拉取oracle镜像(oracle 11.0.2 64bit 企业版 实例名: helowin) Oracle主要在Docker基础上安装,安装环境注意空间和内存,Oracle是一个非常庞大的一个软件, 建议使用网易镜像或阿里镜像网站这里以oracle 11.0.2…...
C++ vector 自定义排序规则(vector<vector<int>>、vector<pair<int,int>>)
vector< int > vector<int> vec{1,2,3,4};//默认从小到大排序 1234 sort(vec.begin(),vec.end()); //从大到小排序 4321 sort(vec.begin(),vec.end(),greater<int>());二维向量vector<vector< int >> vector<vector<int>> vec{{0…...
机器学习 Q-Learning
对马尔可夫奖励的理解 看的这个教程 公式:V(s) R(s) γ * V(s’) V(s) 代表当前状态 s 的价值。 R(s) 代表从状态 s 到下一个状态 s’ 执行某个动作后所获得的即时奖励。 γ 是折扣因子,它表示未来奖励的重要性,通常取值在 0 到 1 之间。…...
产品设计心得体会 优漫动游
产品设计需要综合考虑用户需求、市场需求和技术可行性,从而设计出能够满足用户需求并具有市场竞争力的产品。以下是我在产品设计方面的心得体会: 产品设计心得体会 1.深入了解用户需求:在产品设计之前,需要进行充分的用户调研…...
前端--CSS
文章目录 CSS的介绍 引入方式 代码风格 选择器 复合选择器 (选学) 常用元素属性 背景属性 圆角矩形 Chrome 调试工具 -- 查看 CSS 属性 元素的显示模式 盒模型 弹性布局 一、CSS的介绍 层叠样式表 (Cascading Style Sheets). CSS 能够对网页中元素位置的排版进行像素级精…...
实操指南|如何用 OpenTiny Vue 组件库从 Vue 2 升级到 Vue 3
前言 根据 Vue 官网文档的说明,Vue2 的终止支持时间是 2023 年 12 月 31 日,这意味着从明年开始: Vue2 将不再更新和升级新版本,不再增加新特性,不再修复缺陷 虽然 Vue3 正式版本已经发布快3年了,但据我了…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...
短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
【笔记】WSL 中 Rust 安装与测试完整记录
#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统:Ubuntu 24.04 LTS (WSL2)架构:x86_64 (GNU/Linux)Rust 版本:rustc 1.87.0 (2025-05-09)Cargo 版本:cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...
抽象类和接口(全)
一、抽象类 1.概念:如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象,这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法,包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中,⼀个类如果被 abs…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
pycharm 设置环境出错
pycharm 设置环境出错 pycharm 新建项目,设置虚拟环境,出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...
Spring Boot 与 Kafka 的深度集成实践(二)
3. 生产者实现 3.1 生产者配置 在 Spring Boot 项目中,配置 Kafka 生产者主要是配置生产者工厂(ProducerFactory)和 KafkaTemplate 。生产者工厂负责创建 Kafka 生产者实例,而 KafkaTemplate 则是用于发送消息的核心组件&#x…...
迁移科技3D视觉系统:重塑纸箱拆垛场景的智能革命
一、传统拆垛场景的困局与破局之道 在汽车零部件仓库中,每天有超过2万只异形纸箱需要拆垛分拣。传统人工拆垛面临三大挑战: 效率瓶颈:工人每小时仅能处理200-300件,且存在间歇性疲劳安全隐患:20kg以上重箱搬运导致年…...
CodeBuddy一腾讯内部已有超过 85% 的程序员正在使用de编程工具
大家好,我是程序员500佰,目前正在前往独立开发路线,我会在这里分享关于编程技术、独立开发、技术资讯以及编程感悟等内容。 如果本文能给你提供启发和帮助,还请留下你的一健三连,给我一些鼓励,谢谢。 本文直…...
