Spring使用注解进行注入

news2025/1/13 7:51:18

目录

前言

一、属性注入

1.1 属性注入的优缺点分析

二、Setter注入

2.1 Setter注入优缺点分析

三、构造方法注入

3.1 构造注入的优缺点

四、@Qualifier注解

五、@Resource注解

六、@Resource注解与@Autowired注解的区别


前言

在之前我们就已经了解过了Spring依赖注入的方式,但是前面所说的方式是通过配置文件的方式去进行依赖注入的,我们说配置文件的方式是比较麻烦的,所以在这里将使用注解的方式进行依赖注入。在Spring中使用注解进行依赖注入主要有3种方式:属性注入、Setter注入、构造方法注入。在使用之前先介绍两种常用的注解@Autowired、@Resource下面一起来看


一、属性注入

属性注入是后面开发过程中使用最多的一种方式,即在属性中直接添加注解进而完成注解的效果。

首先创建一个UserDao类,为这个类添加注解(表示将对象存储在Spring中),这里的这个类是与数据库交互的

@Repository
public class UserDao {
    public void login() {
        System.out.println("---数据库核心操作---");
    }
}

创建一个UserService类调用UserDao,这里就需要在UserService类中创建一个userDao对象,进而使用这个对象来调用其核心方法。以往使用的是配置文件的Bean标签的方式,现在只需要一个简单的注解就可以完成这个这个繁琐的过程了

<bean id="userDao" class="com.gl.demo.dao.UserDao"/>
 
<bean id="userService1" class="com.gl.demo.service.UserService1">
    <property name="userDao">
        <ref bean="userDao"/>
    </property>
</bean>
@Service
public class UserService1 {
    // 使用注解对这个userDao对象进行注入
    @Autowired
    private UserDao userDao;

    public void login() {
        userDao.login();
    }
}
@Test
public void test1() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
    UserService1 userService = ctx.getBean("userService1", UserService1.class);
    userService.login();
}

通过上述操作我们发现注解的属性注入确实方便了不少,但是属性注入的方式也是存在缺点的

1.1 属性注入的优缺点分析

优点:

  • 使用方便,只需要变量上面加一个@Autowired即可
  • 代码简洁,可读性高

缺点:

  • 无法为final修饰的变量进行注入

  • 通用性差,无法移植到非IOC容器中使用
  • 不符合单一设计原则

二、Setter注入

这里的Setter注入也就是为这个变量添加一个setter方法,这里添加注解就是添加在setter方法上了,由于这里的测试方法都是一样的,所以这里就不再演示了

@Service
public class UserService2 {
    private UserDao userDao;
    
    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    public void login() {
        System.out.println("Setter注入");
        userDao.login();
    }
}

2.1 Setter注入优缺点分析

优点:

  • 符合单一设计原则

缺点:

  • 不能给final修饰的变量注入

  • 注入的对象可以被修改,由于是setter方法所以都能调用

三、构造方法注入

构造方法顾名思义就是,使用构造方法的方法为变量注入,将注解添加在构造方法上即可

@Service
public class UserService3 {
    private UserDao userDao;

    @Autowired
    public UserService3(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public void login() {
        System.out.println("构造注入");
        userDao.login();
    }
}

3.1 构造注入的优缺点

优点:

  • 可以为final修饰的变量进行注入
  • 不能被修改,由于构造方法只会被加载一次,所以不能被修改
  • 通用性更好,在非IOC容器也能够使用
  • 完全初始化,构造方法会在对象创建之前执行,所以会被完全初始化

缺点:

  • 其实这个是官方推荐的方法,并没有什么明显的缺点,要说缺点的话就是没有属性注入简洁

四、@Qualifier注解

在介绍了@Autowired注解进行注入之后,为什么还要有一个@Resource注解进行注入呢?接下来看一个案例,我们使用@Bean注解将同一个对象注入Spring两次,那么再通过@Autowired注解进行注入会发生什么呢?

首先创建一个User类,再创建一个Users类往Spring中注入两个相同的对象

public class User {
    private String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                '}';
    }
}

这里使用@Bean注解将同一个对象再Spring中创建两次

@Component
public class Users {
    @Bean
    public User user1() {
        User user = new User();
        user.setName("张三");
        return user;
    }

    @Bean
    public User user2() {
        User user = new User();
        user.setName("李四");
        return user;
    }
}

通过@Autowired进行依赖注入,一般情况下这里的注入是没有问题的,但是在Spring中有两个相同的对象。这样获取就会报错

@Controller
public class UserController {
    @Autowired
    private User user;
    public void test() {
        System.out.println(user);
    }
}
@Test
public void test() {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("spring-config.xml");
    UserController users = ctx.getBean("userController", UserController.class);
    users.test();
}

这里的报错信息大概就是,找到了两个user对象分别是user1和user2,不知道你需要的是哪一个 

这里的解决方法就是引入一个新的注解@Qualifier来限制注入的对象是哪一个。(在@Bean注解中方法名就是创建对象的id当然也可以在@Bean注解中自定义id)同理,如果@Qualifier中是user2则打印的是“李四”

@Controller
public class UserController {
    @Autowired
    @Qualifier("user1")
    private User user;
    public void test() {
        System.out.println(user);
    }
}

五、@Resource注解

通过上面的案例我们发现使用两个注解解决问题还是有点麻烦,那么还有什么解决办法呢?这里使用JDK提供的@Resource注解来解决这个问题。那么为什么不直接在@Autowired注解中添加类限定名呢?那是因为@Autowired没有这个功能,这里我们查看源码也可以发现。这里的这个参数表示注入的时候这个Bean是否存在

@Controller
public class UserController {
    //@Autowired
    //@Qualifier("user1")
    @Resource(name = "user2")
    private User user1;
    public void test() {
        System.out.println(user1);
    }
}

最后使用@Resource注解的时候也是可以实现注入功能的

六、@Resource注解与@Autowired注解的区别

  • @Resource是Java自带的,@Autowired是Spring提供的的
  • 相比于@Autowired来说@Resource支持更多的参数设置,例如name等
  • @Autowired支持三种注入方式,但是@Resource不支持构造方法注入

 

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

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

相关文章

word页脚设置,页脚显示第几页共有几页设置步骤

word页脚设置&#xff0c;页脚显示第几页共有几页设置步骤&#xff1a; 具体步骤&#xff1a; 步骤1&#xff1a; 步骤1.1选择页脚---空白页脚 步骤1.2&#xff0c;在"[在此处键入]"&#xff0c;直接输入你需要的格式&#xff0c;如 “第页/共页” 步骤1.3选择第“…

基于ssm服装购物系统

功能如图所示 摘要 基于SSM框架的服装购物系统研究在当今数字化时代具有更为广泛的重要意义。首先&#xff0c;电子商务已成为商业领域的重要发展方向&#xff0c;尤其在全球范围内&#xff0c;服装零售商面临着不断增长的在线购物需求。这种研究能够帮助服装零售商迅速适应市场…

Failed to prepare the device for development

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

班级管理神器

哈喽&#xff0c;亲爱的小红书教育朋友们&#xff01;今天来分享一个重磅好物&#xff1a;班级查询系统&#xff01;是的&#xff0c;你没有听错&#xff0c;让我们的孩子们告别信息混乱&#xff0c;告别手动统计&#xff0c;迎接高效、智能的班级管理新时代&#xff01; 班级查…

appium+selenium自动化测试UI踩坑记录之--判断元素是否存在

判断应用程序元素是否存在&#xff0c;之前使用的代码如下&#xff0c;但是页面跳转后&#xff0c;通过xpath查找信息能查找到跳转前页面的内容&#xff0c;造成信息判断不准确。 # 从selenium.common.exceptions 模块导入 NoSuchElementException类from selenium.common.excep…

mysql主从搭建(gtid)

搭建mysql主从使用三台主机&#xff0c;主机信息如下 ip端口主机名角色10.1.60.803306rabbitmq04salve10.1.60.1143306rabbitmq01slave10.1.60.1153306rabbitmq02master 为每台主机修改主机名并配置hosts hostnamectl set-hostname rabbitmq04 vi /etc/hosts 10.1.60.114 …

【飞控调试】无人机电调哔-哔-哔-哔-哔...发出急促的响声

硬件 飞控&#xff1a;Pixhawk 6C mini 电调&#xff1a;好盈hobbywing Platinum 40A 固件&#xff1a;PX4 V1.13.3 问题 电调上电后&#xff0c;电机发出哔-哔-哔-哔-哔…发出急促的响声&#xff0c;进行电调校准也没用。 解决 在QGC里把SYS_USE_IO参数改成Disabled&…

Hyperledger Fabric搭建测试网络

本文使用的Fabric版本&#xff1a;V2.5.4 Ubuntu系统&#xff1a;16.04LTS 前序文章已经详细介绍了如何安装部署Hyperledger Fabric系统&#xff0c;这里不再赘述。本篇文章主要介绍如何使用Fabric的测试网络。在正式开始之前&#xff0c;有一点需要说明&#xff1a; Hyperled…

IndexError: Target 34 is out of bounds.

问题出现在训练用的标签处&#xff0c;标签超过范围&#xff0c;换了数据集后标签数发生改变&#xff0c;总而言之是目标分类数量超过了你所设置的标签数量的范围&#xff0c;归根结底是全连接参数没有改过来。找到label位置改一下数量

C# 图解教程 第5版 —— 第8章 类和继承

文章目录 8.1 类继承8.2 访问继承的成员&#xff08;*&#xff09;8.3 所有类都派生自 object 类8.4 屏蔽基类的成员8.5 基类访问8.6 使用基类的引用8.6.1 虚方法和覆写方法8.6.2 覆写标记为 override 的方法8.6.3 覆盖其他类型成员&#xff08;*&#xff09; 8.7 构造函数的执…

2011-2021年“第四期”数字普惠金融指数与上市公司匹配(根据省份匹配)/上市公司数字金融指数匹配

2011-2021年“第四期”数字普惠金融指数与上市公司匹配&#xff08;根据省份匹配&#xff09;/上市公司数字金融指数匹配 1、时间&#xff1a;2011-2021年 2、指标&#xff1a;股票代码、年份、行政区划代码、行业名称 、行业代码、所属省份、数字普惠金融指数、覆盖广度、使…

嵌入式学习5大误区,你中招了吗?

目录 误区1&#xff1a;错把自己当稚晖君 误区2&#xff1a;错误的学习方法 误区3&#xff1a;忽略时间成本 误区4&#xff1a;缺乏系统思维 误区5&#xff1a;追求完美主义 误区1&#xff1a;错把自己当稚晖君 稚晖君能够以一己之力创造一个个惊艳的产品&#xff0c;离不…

代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球

代码随想录算法训练营第三十四天 | LeetCode 860. 柠檬水找零、406. 根据身高重建队列、452. 用最少数量的箭引爆气球 文章链接&#xff1a;柠檬水找零 根据身高重建队列 用最少数量的箭引爆气球 视频链接&#xff1a;柠檬水找零 根据身高重建队列 …

StarRocks 荣获 InfoWorld 2023 年最佳开源软件

近日&#xff0c;InfoWorld 公布了 2023 Bossie Awards 获奖名单&#xff0c;StarRocks 作为数据分析领域的明星项目&#xff0c;光荣入列。 InfoWorld 是一家具有全球影响力的信息技术媒体公司&#xff0c;每年都会根据软件对开源界的贡献&#xff0c;发布 Bossie Awards 榜单…

【Javascript】函数返回值的作用

目录 返回值 中断函数 只能写在函数体里面 返回值 function a(){var b3;return b3? 4:5;} console.log(a()); 创建一个函数&#xff0c;给b赋值3&#xff0c; return b3? 4:5; 判断b是不是等于3&#xff0c;如果是就返回4&#xff0c; 如果不是就返回5 中断函数…

JSON数据

一、JSON介绍 Android应用程序界面上的数据信息大部分都是通过网络请求从服务器上获取到的&#xff0c;获取到的数据类型常见的就是JSON。JSON是一种新的数据格式&#xff0c;这种格式的数据不可以直接显示到程序的界面上&#xff0c;需要将该数据解析为一个集合或对象的形式才…

Linux-安装docker-compose

前言&#xff1a;本文建立在服务器中已经存在docker环境的基础上&#xff0c;总结了安装docker-compose过程&#xff0c;以及安装过程中遇到的问题和解决方案。 一、下载docker-compose 在网上找了两种&#xff0c;一种是github官方的&#xff0c;一种是国内的镜像 gitbub官…

Python循环语句(二)

目录 二.for循环1.1for循环的基础语法1.2range语句1.3变量作用域2.for循环嵌套3.循环中断 二.for循环 1.1for循环的基础语法 while循环和for循环的区别 while循环的循环条件是自定义的&#xff0c;自行控制循环条件 for循环是一种轮询机制&#xff0c;是对一批内容进行逐个处…

多种方式计算当天与另一天的间隔天数 Java实现

这里不会记录纯原生写法&#xff0c;因为现在基本都是被工具类封装好的&#xff0c;所以会记录好用的工具类来简化开发&#xff0c;当然自己可以研究写一个年月日各自做减法的纯原生工具类。 踩坑处(System.currentTimeMillis) 这里指的是使用System.currentTimeMillis()方法。…

基于 Qt控制开发板 LED和C语言控制LED渐变亮度效果

## 资源简介 在STM32开发板,板载资源上有两个可自由控制的 LED。如下图原理 图其中我们以操作 LED1 为示例,LED1 为出厂系统的心跳指示灯。 ## 应用实例 想要控制这个 LED,首先出厂内核已经默认将这个 LED 注册成了 gpio-leds类型设备。所以我们可以直接在应用层接口直接…