Spring-IoC 基于xml管理

现大多使用注解方式,xml方式并不简洁,本文仅记录xml用作基础学习。

0、前提 

首先在父项目的pom.xml中配置好依赖们。然后子模块也可以使用这些依赖。
  • 在resource目录下创建Spring的xml文件,名称无要求,本文使用bean.xml。文件最上头的几行为约束,表示可以用哪些标签等,如要使用其他标签,需先在此处添加对应的三行(xmlns:标签名=".../标签名"、xsi:schemaLocation="...  ...",都把链接的末尾改为标签名)
  • 在bean.xml文件中写bean标签:id为类的唯一标识,class为类的全类名(包名+类名)

  • 根据bean.xml文件创建IoC容器

一、获取Bean:

有三种方式获取bean,基于id、基于class、基于id和class一起使用。

1. 根据id获取:getBean("id")

 2. 根据类型获取:getBean(类名.class)

注意事项:
当根据类型获取bean时,要求IoC容器中指定类型的bean有且只能有一个。
当IOC容器中一共配置了多个,根据类型获取时会抛出异常。
期望匹配单实例的bean,但发现了两个,IoC不知道找谁:
只能使用其他两种方式。
 扩展:

接口不能new,只能new接口的实现类。

使用实现类的类型可以获取到bean,所以此处试验接口类型能不能获取bean。

  • 如果组件类实现了接口,根据接口类型可以获取 bean 吗?
        可以,前提是bean唯一
接口UserDao,实现类UserDaoImpl。

  • 如果一个接口有多个实现类,这些实现类都配置了 bean,根据接口类型可以获取 bean 吗?
        不行,因为bean不唯一
接口UserDao,实现类UserDaoImpl、PersonDaoImpl。

 原因与注意事项类似,不知道找谁。
结论: 

        根据类型来获取bean时,在满足bean唯一性的前提下,其实只是看:[对象 instanceof指定的类型」的返回结果,只要返回的是true就可以认定为和类型匹配,能够获取到。

        java中,instanceof运算符用于判断前面的对象是否是后面的类,或其子类、实现类的实例。如果是返回true,否则返回false。也就是说:用instanceof关键字做判断时,instanceof操作符的左右操作必须有继承或实现关系

3. 根据id和类型获取:getBean("id", 类名.class) 


二、依赖注入

依赖注入是指在创建对象时,给属性设置值。

原始写法:通过set方法和有参构造器赋值

有两种实现方式:Setter和构造器。

1. 基于Setter注入:<property>

  • 首先创建类,定义属性和set方法

        在类前使用lombok的@Data注解可以不用手动get、set、toString等。

  • 在bean.xml配置文件中写bean标签,使用<property>标签调用set方法赋值。

        name为属性,value为具体赋值。

2. 基于构造器注入:<constructor-arg>

  • 首先创建类,定义属性和有参构造方法
  • 在bean.xml配置文件中写bean标签,使用<constructor-arg>标签调用有参构造方法赋值。

        name为属性,value为具体赋值。(name也可以用index索引但不推荐,因为顺序要一致)


3. 特殊值处理

3.1 字面量

字面量没有引申含义,就是我们看到的这个数据本身。

使用value属性给bean的属性赋值时,Spring会把value属性的值看做字面量

3.2 null-空值

不能写成如下形式,此时为name属性赋值null字符串

3.3 xml实体:转义

        &lt; 

3.4 CDATA节:<![CDATA[...]]>

4. 特殊类型属性注入 

4.1 对象类型属性

一个类对象中有属性是另一个对象,例如在员工对象中有一个部门对象。

有三种方式:

4.1.1 引用外部bean——ref

在bean.xml中写好两个类的bean,部门bean和员工bean。

在员工bean的部门属性中用ref代替value赋值,ref="部门bean的id"

4.1.2 内部bean

在bean.xml中写员工bean,在员工bean的部门属性中声明部门bean。

4.1.3 级联属性赋值

在引用外部bean的基础上,使用对象.属性可以改变值。

4.2 数组类型属性——<array>标签

员工有多个爱好,用数组表示。

4.3 集合类型属性

4.3.1 List集合——<List>标签

一个部门有多个员工,部门对象bean中有一个员工类型的List。

因为员工是对象类型所以用ref引用外部bean,如果是字符串或其他,用value。

4.3.2 Map集合——<map><entry><key><value><ref>标签

也可以用map-key/value,一个学生有多个老师

4.3.3 引用集合类型的bean——<util:list><util:map>

 由于要使用util标签,要先在bean.xml文件的最上头引入util,否则不能用:

一个学生有多门课-List,多个老师-Map,课和老师为对象类型。

两个lesson对象bean:

两个teacher对象bean:

 student的bean:ref为对应util的id

4.4  p命名空间

要使用p标签,在bean.xml文件最上添加:

使用p命名空间,可以用:p:属性="值"进行赋值,而不用name、value了。

5. 引入外部属性文件

由于bean.xml文件中有很多bean,不利于修改和维护,所以把一些特定的值放在外部文件中,在引入外部文件进行注入。修改时只需修改外部文件,而不用修改配置文件。

常见的如数据库。

5.1 首先在pom.xml文件中添加数据库驱动和数据源等相关依赖。

5.2 创建外部属性文件(resource目录下),一般是.properties后缀格式,定义数据库信息,此处为jdbc.properties

=左边为名字,右边为赋值

5.3 引入外部属性文件:先在bean.xml最上头引用context名称空间,使用<context>标签引入外部属性文件,在bean中的value使用${}表达式完成注入

location为外部属性文件类路径: 

 class为德鲁伊连接池对象路径,value使用外部文件中的名字:

 测试:


三、bean的作用域-scope

注意创建时机不同。

1. 单实例:

两个对象为同一个

 2. 多实例:

两个对象不同


四、bean的生命周期

bean对象从创建到销毁的过程。

1. 生命周期过程:

  1. bean对象创建(调用无参构造器)
  2. 给bean对象设置属性(set方法)
  3. bean的后置处理器(初始化之前)
  4. bean对象初始化(需在配置bean时指定初始化方法)
  5. bean的后置处理器(初始化之后)
  6. bean对象就绪可以使用
  7. bean对象销毁(需在配置bean时指定销毁方法)
  8. IOC容器关闭

2. 后置处理器:

        实现BeanPostProcessor接口,并重写两个方法:postProcessBeforeInitialization和postProcessAfterInitialization。

        还需在IoC容器中配置后置处理器,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IoC容器中所有bean都会执行

class为接口实现类的全类名:

3. 测试

 

 输出:


五、FactoryBean

        FactoryBean是Spring的一种常用机制。帮我们把复杂组件创建的详细过程和繁琐细节都屏蔽起来。和普通的bean不同,配置一个FactorvBean类型的bean,在获取bean的时候得到的并不是class属性中配置的这个类的对象,而是getObject()方法的返回值决定创建什么对象。
        将来整合Mybatis时,Spring就是通过FactoryBean机制来帮我们创建SqlSessionFactory对象的。

使用:

实现FactoryBean接口的类,重写getObject()方法,返回一个对象。

 配置文件:

getBean("user")返回的user对象,而不是class的MyFactoryBean对象。

六、基于xml的自动装配

不使用自动装配即上述中的二、4.1部分使用ref。

在IoC容器匹配bean时,自动为该bean依赖的类类型、接口类型的属性赋值。

有两种方式:byName和byType

创建三个包,controller、Service、dao,其中controller包下有一个UserController类,Service包下有userService接口和实现该接口的userServiceImpl类,dao包下有userDao接口和实现该接口的userDaoImpl类。

1. 在bean.xml中的bean标签内使用autowired ="byType",在IoC容器中根据类型找bean自动装配。最好保证bean唯一
如果没有找到匹配的类型,则该属性不匹配,默认赋值为null。如果找到多个,抛出异常NoUniqeBeanDefinitionException。

 2. autowired ="byName",需保证id标识与类定义中的属性名称一致

 不一致则报错,会赋空值。

参考:b站尚硅谷 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

​网络socket编程(二)——面向流的TCP编程及测试(SocketTool)、Wireshark软件使用

目录 一、书接上回&#xff08;select()函数使用注意事项&#xff09; 二、面向流(TCP)的socket编程 2.1 TCP服务端编程和测试 2.1.1 TCP服务器原理流程图 2.1.2 TCP服务端编程实战 2.1.3 测试 2.2 TCP客户端编程和测试 三、Wireshark抓包软件的使用 3.1 Wireshark是什…

Flutter 应用数据持久化指南

1. 介绍 1.1 什么是数据持久化&#xff1f; 数据持久化是指将应用程序中的数据保存在持久存储介质&#xff08;如硬盘、数据库等&#xff09;中的过程。在计算机科学领域&#xff0c;持久化数据是指数据在程序退出或系统关机后仍然存在的能力。这种持久性使得数据可以在不同的…

报告分享:2024 年小米汽车产业链分析及新品上市全景洞察报告

本文主要介绍了小米汽车在市场中的布局和优势&#xff0c;以及其面临的劣势与挑战。小米汽车凭借品牌、技术和成本三大核心优势&#xff0c;展现出强大的市场竞争力和品牌影响力&#xff0c;为消费者带来全新的汽车生活体验。文章还分析了小米汽车与小米生态链的协同效应&#…

CTF下加载CTFtraining题库以管理员身份导入 [HCTF 2018]WarmUp,之后以参赛者身份完成解题全过程

-------------------搭建CTFd------------------------------ 给大家介绍一个本地搭建比较好用的CTF比赛平台&#xff1a;CTFD。 CTFd是一个Capture The Flag框架&#xff0c;侧重于易用性和可定制性。它提供了运行CTF所需的一切&#xff0c;并且可以使用插件和主题轻松进行自…

如何在Java中,使用jackson实现json缩进美化

导入的maven依赖 <!--json--> <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.10.0</version> </dependency>示例代码 json要是String类型 public…

解决el-table设置固定高度后,展示不同列时表格高度变小bug

解决el-table设置固定高度后&#xff0c;展示不同列时表格高度变小bug 1、需求分析2、解决方案 1、需求分析 在el-table使用过程中&#xff0c;选择多个参数展示更多列时会出现高度变小问题究其原因可知是el-table列动态发生变化后&#xff0c;el-table__body-wrapper的高度变…

【NLP笔记】LLM应用之AI Agent LangChain实战

文章目录 AI Agent概述LangChain实战构建prompt模版LLM调用调用HuggingFace开源大模型&#xff08;在线&#xff09;调用HuggingFace开源大模型&#xff08;本地&#xff09;调用文心一言 ChainsSingle ChainSequential ChainSimple Sequential ChainComplex Sequential Chain …

Apache Pulsar源码解析之Lookup机制

引言 在学习Pulsar一段时间后&#xff0c;相信大家也或多或少听说Lookup这个词&#xff0c;今天就一起来深入剖析下Pulsar是怎么设计的它吧 Lookup是什么 在客户端跟服务端建立TCP连接前有些信息需要提前获取&#xff0c;这个获取方式就是Lookup机制。所获取的信息有以下几种…

java 解析c语言程序xml数据文件

GetMapping("/getHostMenuButtons")Operation(summary "创建试卷分类")PermitAll // PreAuthorize("ss.hasPermission(jd:index:query)")public JSONObject getJd() {//1、读取文件并转换为Document文档对象Document doc null;try {doc ne…

Spring Boot 学习(2)——HelloWorld

HelloWorld&#xff01;全宇宙码农的第一个&#xff08;行&#xff09;程序&#xff08;代码&#xff09;。 1、创建项目 打开idea&#xff0c;新建一个maven项目。 1&#xff09;选择项目sdk&#xff08;本例是1.8&#xff09; 2&#xff09;输入GroupId&#xff08;co…

Android JNI 调用第三方SO

最近一个项目使用了Go 编译了一个so库&#xff0c;但是这个so里面还需要使用第三方so库pdfium, 首先在Android工程把2个so库都放好 在jni中只能使用dlopen方式&#xff0c;其他的使用函数指针的方式来调用&#xff0c;和windows dll类似&#xff0c;不然虽然编译过了但是会崩溃…

日志服务 HarmonyOS NEXT 日志采集最佳实践

作者&#xff1a;高玉龙&#xff08;元泊&#xff09; 背景信息 随着数字化新时代的全面展开以及 5G 与物联网&#xff08;IoT&#xff09;技术的迅速普及&#xff0c;操作系统正面临前所未有的变革需求。在这个背景下&#xff0c;华为公司自主研发的鸿蒙操作系统&#xff08…