Spring framework Day10:JSR330注入注解

news2025/5/25 5:56:17

前言

JSR330是Java社区标准化进程(Java Community Process,简称JCP)中的一个规范,全名为"Dependency Injection for Java",即Java的依赖注入规范。它定义了一组注解和相关的规范,用于实现依赖注入(Dependency Injection,简称DI)。

依赖注入是一种设计模式,旨在解耦应用程序中的不同模块或组件之间的依赖关系。通过依赖注入,可以将对象的创建、维护和配置等责任从使用对象的代码中剥离出来,并由容器负责提供和注入所需的依赖项。

 

一、开始学习

本次主学习三个注解,@RequiredArgsConstructor、@Inject、@Named。那么它们分别是什么意思,有什么用呢?

@RequiredArgsConstructor@Inject@Named是JSR330规范中的注解,用于实现依赖注入。

  1. @RequiredArgsConstructor:这是一个Lombok注解,而不是JSR330规范中的注解。它可以用于生成一个包含所有标记为final@NonNull的字段的构造函数。这样,在使用@RequiredArgsConstructor注解的类中,就无需手动编写构造函数,Lombok会自动帮我们生成。这在依赖注入中特别有用,可以省去手动编写大量的构造函数代码。

  2. @Inject:这是JSR330规范中的注解,用于标记需要进行依赖注入的构造方法、字段或者方法。通过在目标类中标记@Inject,依赖注入框架会在需要的时候自动实例化并注入相应的依赖项。

  3. @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 {
    @Override
    public 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 {
    @Override
    public 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这些注解在依赖注入中可以提供以下好处:

  1. @RequiredArgsConstructor注解:该注解是Lombok库提供的注解,用于自动生成构造函数,其中参数为被声明为final或者被标记为@NonNull的字段。使用该注解可以简化代码,省略手动编写构造函数的过程,从而提高开发效率。

  2. @Inject注解:该注解是Java依赖注入(JSR-330)规范中定义的注解,用于在运行时自动注入所需的实例。使用该注解可以避免手动处理对象的依赖关系,框架会自动将所需的实例注入到相应的位置。这样可以减少与依赖相关的代码量和复杂度,并且降低耦合度,使代码更加可维护和可测试。

  3. @Named注解:该注解也是Java依赖注入(JSR-330)规范中定义的注解,用于为bean指定唯一的名称或id。当存在多个实现类时,可以使用@Named注解来标识不同的实现类,然后在注入时根据指定的bean名称进行选择注入哪个实例。使用@Named注解可以更精确地控制依赖注入的目标对象,提高灵活性。

综上所述,使用@RequiredArgsConstructor可以简化构造函数的编写,提高代码效率;@Inject可以自动注入依赖,减少手动管理对象依赖关系的代码量和复杂度;@Named可以为bean指定唯一的名称或id,使得在存在多个实现类时更精确地控制注入目标。这些注解能够有效地提高代码的可读性、可维护性和可测试性,同时减少出错的可能性。

四、gitee 案例

案例完整地址:https://gitee.com/qiu-feng1/spring-framework.git

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1088477.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Prometheus:优秀和强大的监控报警工具

文章目录 概述Prometheus的底层技术和原理数据模型数据采集数据存储查询语言数据可视化 Prometheus的部署Prometheus的使用配置数据采集目标查询监控数据设置警报规则 查看数据可视化总结 概述 Prometheus是一款开源的监控和警报工具&#xff0c;用于收集和存储系统和应用程序…

NodeMCU清除Wifi信息

问题&#xff1a;NodeMCU连上一个Wifi后无法再连接到其他Wifi 解决方法&#xff1a;先清除Wifi信息 wifi.setmode(wifi.NULLMODE) wifi.sta.clearconfig()

Java学生管理系统(纯练手)

Java学生管理系统&#xff08;纯练手&#xff09; 该系统主要功能如下&#xff1a; ​添加学生&#xff1a;通过键盘录入学生信息&#xff0c;添加到集合中删除学生&#xff1a;通过键盘录入要删除学生的学号&#xff0c;将该学生对象从集合中删除修改学生&#xff1a;通过键…

《3D 数学基础》几何检测-最近点

目录 1. 直线上的最近点 2. 射线上的最近点 3. 点到平面的距离 4. 圆或球上的最近点 5. AABB上的最近点 1. 直线上的最近点 q是距离q的最近点&#xff0c;也就是q在直线上的投影。 其中p是直线上的点&#xff08;向量表示&#xff09;&#xff0c;n是直线的法向量&#x…

基于行波理论的输电线路防雷保护

摘要 随着科技的发展&#xff0c;电力已成为最重要的资源之一&#xff0c;如何保证电力的供应对于国民经济发展和人民生活水平的提高都有非常重要的意义。输电线路的防雷保护就是重点之一。架空输电线路分布很广&#xff0c;地处旷野&#xff0c;易遗受雷击&#xff0c;线路的雷…

企业全域风控管理的最优解

后疫情时代&#xff0c;市场竞争加剧&#xff0c;呈现白热化状态&#xff0c;同时伴随企业的业务拓展、经营管理领域逐渐增多&#xff0c;企业面临的内外部风险、问题也呈指数增长趋势。 因此&#xff0c;企业在面临内外风险的双重压力下&#xff1a; 如何确保企业经营管理战…

【问题解决:配置】解决spring mvc项目 get请求 获取中文字符串参数 乱码

get类型请求的发送过程 前端发送一个get请求的过程&#xff1a; 封装参数进行URL编码&#xff0c;也就是将中文编码成一个带有百分号的字符串&#xff0c;具体可以在这个网站进行测试。http://www.esjson.com/urlEncode.html 进行Http编码&#xff0c;这里浏览器或者postman都…

【力扣1704】判断字符串的两半是否相似

&#x1f451;专栏内容&#xff1a;力扣刷题⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、题目描述二、题目分析 一、题目描述 题目链接&#xff1a;判断字符串的两半是否相似 给你一个偶数长度的字符串 s 。…

判断两个二叉树是否相等

bool isSameTree(struct TreeNode* p, struct TreeNode* q) {//两个都为空if(pNULL&&qNULL){return true;}//有一个为空if(pNULL||qNULL){return false;}//两个不为空&#xff0c;但值不相同if(p->val!q->val){return false;}//值相同return isSameTree(p->le…

微信小程序个人账号申请和配置详细教程

一、注册小程序管理账号 1、注册方法 在微信公众平台官网首页&#xff08;mp.weixin.qq.com&#xff09;&#xff0c;点击右上角的“立即注册”按钮。 2、选择注册的账号类型 选择“小程序”&#xff0c;点击“查看类型区别”可查看不同类型账号的区别和优势。 3、填写邮箱和…

如何利用 J2L3x 实现团队化作业

在当今快节奏的团队工作环境中&#xff0c;始终有一项问题不断困扰着许多企业&#xff0c;那就是团队成员之间的协同工作。这个问题越来越凸显出来&#xff0c;并在某种程度上影响了团队的效率和生产力。然而&#xff0c;随着科技的不断发展&#xff0c;有许多新的工具和平台可…

【学习笔记】Spring Security 01 认识Spring Security的重要特征(Features)

Spring Security 零、概述 Spring Security&#xff08;简称SS&#xff09;是一个高可用的、可自定义的身份认证和鉴权控制的框架。 类似的框架还有Shiro。 需求场景&#xff1a; 现今流行的web开发中&#xff0c;安全的第一位。 原本的鉴权开发流程&#xff1a;springweb自…

堆专题3 删除堆顶元素

题目&#xff1a; 样例&#xff1a; 输入 6 3 2 6 5 8 7 输出 7 5 6 3 2 思路&#xff1a; 堆顶的删除&#xff0c;就是取 或者 覆盖掉 h[1]&#xff0c;其中覆盖掉 h[1] 的操作&#xff0c;用向下调整操作堆即可&#xff0c;向下调整的过程相对简单&#xff0c;只需要将堆尾…

如何提高团队协作效率?看完这篇就懂了(附工具)

在竞争激烈的现代工作环境中&#xff0c;团队协作被认为是成功的关键之一。团队协作能够提高效率&#xff0c;增强创造力&#xff0c;并帮助团队成员达成共同目标。无论是在大公司还是小企业中&#xff0c;团队协作都是不可或缺的。在这篇文章中&#xff0c;我们将分享如何通过…

提高测试用例覆盖全面性 5大技巧

测试用例覆盖率越高&#xff0c;有助于尽早发现潜在的问题和Bug&#xff0c;从而保障了软件的质量和稳定性。而测试用例覆盖率可以帮助测试团队评估测试的全面性&#xff0c;发现测试用例的盲点和不足之处&#xff0c;从而提高测试的效率&#xff0c;帮助测试团队优化测试资源的…

OpenCV4(C++)—— 图像连通域的详细分析

文章目录 前言一、connectedComponents函数二、connectedComponentsWithStats函数 前言 图像连通域&#xff0c;其实就是图像分割的一种方法。它通过检测像素之间的连接关系和相似性来划分图像中的区域&#xff0c;以便进行后续处理。图像邻域和图像邻域分析就不介绍了&#x…

Redis第四五六章 持久化事务主从复制

Redis ⽀持 RDB 和 AOF 两种持久化机制&#xff0c;持久化功能有效地避免因进程退出造成数据丢失问题&#xff0c; 当下次重启时利⽤之前持久化的⽂件即可实现数据恢复。 目录 第四章 持久化 4.1 RDB 4.1.1 触发机制 4.1.2 流程说明 4.1.3 RDB ⽂件的处理 4.1.4 RDB 的优…

Autoform R11 R10 R8共存绿色免安装版(解压即用)

使用说明&#xff1a; 如杀毒软件报毒&#xff0c;请关闭。 保证路径正确D:\Autoform 1.首次使用&#xff0c;请点击“首次运行使用.vbs” &#xff08;以后就不用点了&#xff09; 2.打开R8~R11快捷方式即可使用 3.如果提示证书报错&#xff0c; 就重启电脑后就可以了&#…

信必优收到全国性综合类证券客户表扬信

近日&#xff0c;信必优收到全国性综合类证券客户表扬信&#xff0c;客户高度表扬我司驻场员工认真负责的态度和专业扎实的技术能力&#xff0c;任务承担快&#xff0c;工作效率高&#xff0c;对项目顺利开展做出了积极贡献。 客户成立于1988年&#xff0c;在全国21个省级区域…

mars3d使用自己的字体库添加对应的图标

需要引入对应的文件 引入对应的图标文件 使用 效果