【Spring进阶系列丨第六篇】Spring的Bean管理(基于注解)

news2024/10/5 16:41:34

文章目录

  • 一、说明
  • 二、用于创建对象的
    • 2.1、Component注解
      • 2.1.1、定义Bean
      • 2.1.2、主配置文件配置扫描注解
      • 2.1.3、测试
      • 2.1.4、Component注解总结
    • 2.2、Controller注解
    • 2.3、Service注解
    • 2.4、Repository注解
  • 三、用于注入数据的
    • 3.1、Autowired注解
      • 3.1.1、定义Bean
      • 3.1.2、主配置文件配置扫描注解
      • 3.1.3、测试
      • 3.1.4、改造
      • 3.1.5、总结
    • 3.2、Qualifier注解
      • 3.2.1、定义Bean
      • 3.2.2、总结
    • 3.3、Resource注解
      • 3.3.1、定义Bean
      • 3.3.2、总结
    • 3.4、Value注解
      • 3.4.1、案例1
        • 3.4.1.1、定义Bean
        • 3.4.1.2、测试
      • 3.4.2、案例2
        • 3.4.2.1、创建db.properties文件
        • 3.4.2.2、主配置文件需要将properties文件引入进来
        • 3.4.2.3、定义Bean
        • 3.4.2.4、测试
      • 3.4.3、总结
    • 3.5、大总结
  • 四、用于改变Bean的作用域的
    • 4.1、定义Bean
    • 4.2、测试
    • 4.3、总结
  • 五、和Bean的生命周期相关的
    • 5.1、定义Bean
    • 5.2、测试
    • 5.3、总结

在这里插入图片描述

一、说明

回顾一下基于xml配置的Spring对Bean的管理 ,对Bean的完整管理如下所示:

<bean id="" class="" init-method="" destroy-method="" scope="">
    <property name="" value=""/>
    <property name="" ref=""/>
</bean>

分析可以发现:我们对Bean的管理就四个方面,分别是:

  • 用于创建对象的
  • 用于注入数据的
  • 用于改变Bean的作用域的
  • 和Bean的生命周期相关的

其实对于注解来说,也是包括了这四个方面,换句话说,使用注解的方式管理Bean和使用xml的方式管理Bean作用是完全一样的,区别仅仅在于配置的形式不同而已。

二、用于创建对象的

2.1、Component注解

2.1.1、定义Bean

@Component
public class DogService {
    
}

2.1.2、主配置文件配置扫描注解

<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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 告诉spring在创建容器时要扫描的包   -->
    <context:component-scan base-package="cn.bdqn"/>

</beans>

2.1.3、测试

 @Test
public void testDogServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        DogServiceImpl dogService = (DogServiceImpl) ac.getBean("dogServiceImpl");

        System.out.println(dogService);
}

2.1.4、Component注解总结

  • 作用

    ​ 用于把对当前修饰的类创建出来,并存放到Spring容器中。

  • 属性

    ​ a. 用该注解所创建的对象默认的id名称是当前类名,且首字母改小写

    ​ b. 可以通过value属性手动的指定bean的id。

2.2、Controller注解

​ 一般用在表现层,例如SpringMVC、Struts2

2.3、Service注解

​ 一般用在业务层,例如Service层

2.4、Repository注解

​ 一般用在持久层7.2.5、总结

  • Controller、Service、Repository这三个注解他们的作用和属性与Component是一模一样。
  • 既然一模一样,之所以Spring框架还要提供,主要是Spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰。
  • 他们的作用就和在XML配置文件中编写一个标签实现的功能是一样的

三、用于注入数据的

3.1、Autowired注解

作用:

​ 自动按照类型注入。

3.1.1、定义Bean

// 用户service接口
public interface UserService {
	public void printUserDao();
}
// 用户service接口实现,bean的名称改为:userService
@Service("userService")
public class UserServiceImpl implements UserService {
	
  	@Autowired
    private UserDao userDao;

    // 打印UserDao,看是否可以将值打印出来,如果打印出来说明值真的注入成功了
    public void printUserDao(){
        System.out.println(userDao);
    }
}
// 用户UserDao接口
public interface UserDao {

}
// 用户UserDao接口实现,bean的名称改为:userDao01
@Repository("userDao01")
public class UserDaoImpl01 implements UserDao {

}

3.1.2、主配置文件配置扫描注解

<beans>
	<!-- 告诉spring在创建容器时要扫描的包   -->
    <context:component-scan base-package="cn.bdqn"/>
</beans>

3.1.3、测试

@Test
public void testUserServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        UserService userService = (UserService) ac.getBean("userService");

        userService.printUserDao();	// cn.bdqn.dao.impl.UserDaoImpl@7a52f2a2
}

3.1.4、改造

假设系统中存在两个UserDao的实现,现在再添加一个。现在再添加测试:

@Repository("userDao02")
public class UserDaoImpl02 implements UserDao {

}

再次运行程序,会发现,程序报错:

No qualifying bean of type 'cn.bdqn.dao.UserDao' available: expected single matching bean but found 2: userDao01,userDao02

翻译:没有找到一个可用的UserDao,期望能够匹配一个,但是发现了2个。换句话说,由于是根据类型匹配的,而userDao01,userDao02都是符合注入的类型的,不知道要用哪个了.

该如何解决呢?既然Spring不知道具体要用哪个了,那我们由开发者来去指定其中的一个告诉Spring你就用这个注入就可以了,那么实现方式就是:通过名称告诉即可

解决方案:

@Service("userService")
public class UserServiceImpl implements UserService {

  	// 将变量的名称修改为userDao01,那么依赖注入的时候就使用UserDaoImpl01
    @Autowired
    private UserDao userDao01;
}

再次测试,程序正常执行。

3.1.5、总结

  • 该注解是根据类型自动注入,假如只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功。
  • 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。
  • 如果容器中有多个bean对象类型和要注入的变量类型匹配,则可能会发生错误,解决办法就是修改变量的名称为其中的某一个bean的名称

3.2、Qualifier注解

​ 在7.3.1章节使用Autowired注解的时候,会存在一个问题,就是如果系统中存在多个类型的Bean都匹配的时候,就会找不到到底要使用哪个Bean对象了,会报错,我们采取的解决办法是:修改变量名即可解决 , 但是这种做法实际上是挺菜的,我现在就想使用userDao这个变量名,那么能否有一种更好的解决办法呢?答案是肯定的,即使用Qualifier注解。

3.2.1、定义Bean

​ Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean,修改如下:

public class UserServiceImpl implements UserService {

    @Autowired
    @Qualifier(value = "userDao01")	// 通过此注解中的value属性明确指定要用哪个name的bean
    private UserDao userDao;
}

3.2.2、总结

  • 在按照类型注入的基础之上再按照名称注入,它在给类的成员变量注入时不能单独使用,需要搭配Autowired注解。

3.3、Resource注解

3.3.1、定义Bean

​ Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean,修改如下:

@Service("userService")
public class UserServiceImpl implements UserService {

    @Resource(name = "userDao01")
    private UserDao userDao;
}

3.3.2、总结

  • 该注解采用的是直接按照bean的id注入,它可以独立使用,name用于指定bean的id。

注意:

使用Autowired、Qualifier以及Resource这三个注解都只能注入其他bean类型的数据,对于基本数据类型和String类型是无法通过使用该3个注解实现。同时,对于集合数据类型的注入只能通过XML来实现。


3.4、Value注解

作用:

​ 用于注入基本类型和String类型的数据。

3.4.1、案例1

3.4.1.1、定义Bean
@Component("jdbcUtils")
public class JdbcUtils {

    @Value("com.mysql.jdbc.Driver")
    private String driverClass;
}
3.4.1.2、测试
@Test
public void testJdbcUtils() throws Exception{
    // 1、读取主配置文件信息,获取核心容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    JdbcUtils utils = (JdbcUtils) ac.getBean("jdbcUtils");

    System.out.println(utils);	// com.mysql.jdbc.Driver
}

3.4.2、案例2

如果Value注解用于案例1,那这样太菜了,我们要为driverClass这个变量赋值,那岂不是直接赋值得了,还需要搞一个Value直接赋值吗?显然是没有必要的,所以一般来说,Value注解常用于对配置文件内容的读取。

3.4.2.1、创建db.properties文件
driverClass=com.mysql.jdbc.Driver
port=3306
3.4.2.2、主配置文件需要将properties文件引入进来
<beans>
	
  	<!-- 告诉spring在创建容器时要扫描的包   -->
    <context:component-scan base-package="cn.bdqn"/>
    
  	<!-- 将properties文件引入到Spring框架中-->
    <context:property-placeholder location="classpath:db.properties"/>
</beans>
3.4.2.3、定义Bean
@Component("jdbcUtils")
public class JdbcUtils {

    @Value("${driverClass}")
    private String driverClass;

    @Value("${port}")
    private Integer port;
}
3.4.2.4、测试
@Test
public void testJdbcUtils() throws Exception{
    // 1、读取主配置文件信息,获取核心容器对象
    ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

    JdbcUtils utils = (JdbcUtils) ac.getBean("jdbcUtils");

    System.out.println(utils);	// com.mysql.jdbc.Driver,3306
}

3.4.3、总结

该注解通过可以实现对基本数据类型和String类型的注入,并且是支持使用Spring的EL表达式。那么对于Spring的EL表达式的语法就是:${表达式}。

3.5、大总结

以上注解的作用就和在xml配置文件中的bean标签中写一个标签的作用是一样的

四、用于改变Bean的作用域的

方式:

  • 使用Scope注解,作用是用于指定bean的作用范围。该注解有一个value属性,可以指定范围的取值,常用取值:singleton、 prototype
  • 该Scope注解默认的value值就是单例的【singleton】

4.1、定义Bean

Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean修改作用域,修改如下:

@Service("userService")
@Scope("singleton")
public class UserServiceImpl implements UserService{
  
}

4.2、测试

@Test
public void testUserServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        UserService userService = (UserService) ac.getBean("userService");
        UserService userService2 = (UserService) ac.getBean("userService");

        System.out.println(userService == userService2); // true
}

改造一下:如果将上例的UserServiceImpl中的Scope改为prototype,则再次测试的时候会返回false。

4.3、总结

Scope该注解的作用就和在bean标签中使用scope属性实现的功能是一样的

五、和Bean的生命周期相关的

5.1、定义Bean

​ Bean的定义,仍然采用7.3.1章节所定义好的Bean,唯一的区别是UserServiceImpl这个Bean添加了一个初始化方法和销毁方法。

@Service("userService")
public class UserServiceImpl implements UserService {

    @PostConstruct
    public void init(){
        System.out.println("对象初始化了");
    }
    
    @PreDestroy
    public void destroy(){
        System.out.println("对象销毁了");
    }
}

5.2、测试

@Test
public void testUserServiceImpl() throws Exception{
        // 1、读取主配置文件信息,获取核心容器对象
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");

        ac.close();
}

// 对象初始化了
// 对象销毁了

5.3、总结

这个两个注解作用就和在bean标签中使用init-method和destroy-methode的作用是一样的。


在这里插入图片描述

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

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

相关文章

《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置(6)

接前一篇文章&#xff1a;《PCI Express体系结构导读》随记 —— 第I篇 第2章 PCI总线的桥与配置&#xff08;5&#xff09; 2.2 HOST主桥 本节以MPC8548处理器为例&#xff0c;说明HOST主桥在PowerPC处理器中的实现机制&#xff0c;并简要介绍x86处理器系统使用的HOST主桥。 …

【springboot+vue项目(零)】开发项目经验积累(处理问题)

一、VUEElement UI &#xff08;一&#xff09;elementui下拉框默认值不是对应中文问题 v-model绑定的值必须是字符串&#xff0c;才会显示默认选中对应中文&#xff0c;如果是数字&#xff0c;则显示数字&#xff0c;修改为&#xff1a; handleOpenAddDialog() {this.dialogT…

【Emgu.CV教程】第24篇 、色彩处理之LUT()查找表转换颜色

LUT (Look-Up Table)查找表转换&#xff0c;是对原始图像的像素数值进行快速转换&#xff0c;以实现图像的像素压缩目的。LUT()函数的官方定义如下&#xff1a; public static void LUT(IInputArray src, // 输入图像IInputArray lut, // 查找表IOutputArray dst, // 输出图像…

2023春季李宏毅机器学习笔记 05 :机器如何生成图像

资料 课程主页&#xff1a;https://speech.ee.ntu.edu.tw/~hylee/ml/2023-spring.phpGithub&#xff1a;https://github.com/Fafa-DL/Lhy_Machine_LearningB站课程&#xff1a;https://space.bilibili.com/253734135/channel/collectiondetail?sid2014800 一、图像生成常见模型…

提示循环引用 一个循环引用但无法列出导致循环的引用且文件打不开无法修改

目录 设备环境&#xff1a; 提示内容&#xff1a; 具体错误问题描述&#xff1a; 图示&#xff1a; Office 报错 WPS 报错 问题分析&#xff1a; 问题解决&#xff1a; 关注我的 GitHub&#xff08;魔法网络访问&#xff09;&#xff1a; 设备环境&#xff1a; Window…

(湖科大教书匠)计算机网络微课堂(下)

第四章、网络层 网络层概述 网络层主要任务是实习网络互连&#xff0c;进而实现数据包在各网络之间的传输 因特网使用TCP/IP协议栈 由于TCP/IP协议栈的网络层使用网际协议IP&#xff0c;是整个协议栈的核心协议&#xff0c;因此TCP/IP协议栈的网络层常称为网际层 网络层提供…

1.1 理解大数据(2)

小肥柴的Hadoop之旅 1.1 理解大数据&#xff08;2&#xff09; 目录1.1 理解大数据1.1.3 大数据概述1.1.4 更多思考 参考文献和资料 目录 1.1 理解大数据 1.1.3 大数据概述 step_0 大数据定义 【《大数据算法设计分析》】&#xff1a; 通常来讲大数据&#xff08;Big Data&am…

【Linux操作系统】探秘Linux奥秘:Linux 操作系统的解密与实战

&#x1f308;个人主页&#xff1a;Sarapines Programmer&#x1f525; 系列专栏&#xff1a;《操作系统实验室》&#x1f516;诗赋清音&#xff1a;柳垂轻絮拂人衣&#xff0c;心随风舞梦飞。 山川湖海皆可涉&#xff0c;勇者征途逐星辉。 目录 &#x1fa90;1 初识Linux OS …

目标跟踪算法中的卡尔曼滤波学习

在使用多目标跟踪算法时&#xff0c;接触到卡尔曼滤波&#xff0c;一直没时间总结下&#xff0c;现在来填坑。 1. 背景知识 在理解卡尔曼滤波前&#xff0c;有几个概念值得考虑下&#xff1a;时序序列模型&#xff0c;滤波&#xff0c;线性动态系统 1. 时间序列模型 时间序…

Elasticsearch:Serarch tutorial - 使用 Python 进行搜索 (一)

本实践教程将教你如何使用 Elasticsearch 构建完整的搜索解决方案。 在本教程中你将学习&#xff1a; 如何对数据集执行全文关键字搜索&#xff08;可选使用过滤器&#xff09;如何使用机器学习模型生成、存储和搜索密集向量嵌入如何使用 ELSER 模型生成和搜索稀疏向量如何使用…

【KingbaseES】实现MySql函数Field

CREATE OR REPLACE FUNCTION field(value TEXT, VARIADIC arr TEXT[]) RETURNS INT AS $$ DECLAREi INT; BEGINFOR i IN 1 .. array_length(arr, 1) LOOPIF arr[i] value THENRETURN i;END IF;END LOOP;RETURN 0; END; $$ LANGUAGE plpgsql IMMUTABLE;

【Mac】Mac新机配置前端环境教程

1、先安装谷歌浏览器&#xff0c;稳定版 作为一名前端程序员&#xff0c;和浏览器打交道肯定是必不可少的。Chrome&#xff0c;Edge 都有着丰富的扩展资源。你可以下载插件帮助你更好的在工作中调试代码。 React Developer Tools Vue.js devtools GraphQL developer tools 如…

信号量原理及其应用

一、信号量定义 信号量是一种用于保护临界资源的同步机制。它可以用来控制对共享资源的访问&#xff0c;以避免并发访问导致的数据不一致或竞争条件。信号量的PV操作是原子操作&#xff0c;即不可被中断的操作。 在信号量的操作中&#xff0c;P操作&#xff08;也称为wait操作…

imgaug库指南(四):从入门到精通的【图像增强】之旅

引言 在深度学习和计算机视觉的世界里&#xff0c;数据是模型训练的基石&#xff0c;其质量与数量直接影响着模型的性能。然而&#xff0c;获取大量高质量的标注数据往往需要耗费大量的时间和资源。正因如此&#xff0c;数据增强技术应运而生&#xff0c;成为了解决这一问题的…

AIGC实战——自回归模型(Autoregressive Model)

AIGC实战——自回归模型 0. 前言1. 长短期记忆网络基本原理2. Recipes 数据集3. 处理文本数据3.1 文本与图像数据处理的差异3.2 文本数据处理步骤 4. 构建 LSTM 模型4.1 模型架构4.2 LSTM 计算流程4.3 训练 LSTM 5. LSTM 模型分析小结系列链接 0. 前言 自回归模型 (Autoregres…

基于gamma矫正的照片亮度调整(python和opencv实现)

import cv2 import numpy as npdef adjust_gamma(image, gamma1.0):invGamma 1.0 / gammatable np.array([((i / 255.0) ** invGamma) * 255 for i in np.arange(0, 256)]).astype("uint8")return cv2.LUT(image, table)# 读取图像 original cv2.imread("tes…

使用 SpringSecurity 发送POST请求出现 403

问题场景 在使用 SpringSecurity 时对一些访问权限进行了设置, 在用户请求资源时出现了403错误 , 通过检查代码发现请求权限是开放的, 并且切换成 GET 请求也是可以通过, 换成POST 请求就无法通过。 解决方法 在 SpringSecurity 中关闭 CSRF 因为 前端向后台发送 post 请求…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《考虑分布式资源交易的气电综合能源配网系统出清模型》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主的免费专栏栏目《论文与完整程序》 这个标题涉及到气电综合能源配网系统的出清模型&#xff0c;特别强调了对分布式资源交易的考虑。以下是对标题中关键术语的解读&#xff1a; 气电综合能…

java SSM体育器材租借管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM体育器材租借管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要…