Spring(下)

接上篇,从第八个问题讲起

八.Spring工厂创建复杂对象

1.什么是复杂对象

简单对象就是可以直接new出来的,也就是直接调用构造方法创建

所以复杂对象就是不能直接通过调用构造方法创建。就比如JDBC中的Connection

2.三种方法

(1).FactoryBean接口

首先准备一个类,实现上述接口,进行文件配置。里面有三个方法:

getObject方法是用于书写创建复杂对象的代码,并将复杂对象作为方法返回值返回

getObjectType方法是返回复杂对象的class对象

isSingleton方法:若该对象只需创建一次(就是说每次都是用同一个对象),就让这个方法返回true;若每次使用都要创建一个新的对象,就让它返回false。

示例:

我们拿数据库建立连接来举例。既然要使用数据库,我们就要先引入数据库的依赖。

首先来实现getObject方法

其次就是getObjectType方法:

最后就是isSingleton方法

进行文件配置:

获取连接对象:

如上,虽然在配置文件中指定的是FactoryBean接口的实现类,但是获取到的却是Connection对象!!!这就是为啥要实现factorybean接口,原理会在后面讲到

细节分析:
如果就想获得factoryBean对象

在getbean方法中的conn前面加一个&即可

isSingleton方法

如果返回true,没那么每次创建的对象都是同一个:

如果返回false,则不是同一个:

依赖注入

对于connectionFactoryBean来说,下面几个内容是很重要的,是它所依赖的

所以要对他们进行set注入:

首先设置成成员变量,然后提供set方法,再去配置文件

FactoryBean实现原理

首先根据getBean传入的conn字符串获取对应bean标签的相关信息,

其次使用instanceof判断是否是factorybean的实现类

如果是就去执行重写的getObject方法来获取到connection对象,最后返回对象

总结

FactoryBean是Spring种用于创建复杂对象的方式,也是Spring原生提供的

(2).实例工厂

优势

实例工厂能够避免Spring框架的侵入,避免使用Spring提供的FactoryBean。

实力工厂也可以整合遗留系统

示例

写一个ConnectionFactory类作为遗留系统,

然后再配置文件中进行如下配置:

用到了factory-bean属性和factory-method属性

这样就把遗留系统整合了

(3).静态工厂

将getConnection方法换成静态的

配置文件如上

九.控制对象创建的次数

1.简单对象

在bean标签上加一个scope标签,值为singleton则只能创建一个对象,值为prototype(译为原型)则每次都创建新的对象

scope的值默认为singleton

2.复杂对象

就是使用issingleton方法。如果没有重写这个方法,那就还是默认使用scope属性,并且默认为singleton

3.为啥要控制?

有些对象,比如userDao,就可以被共用,有些不可以

好处:节省不必要的内存浪费

十.对象的生命周期

共分为三个阶段

1.创建阶段

Spring工厂何时创建对象?

当scope为singleton时,就是在Spring工厂创建的同时(也就是new ClassPathXmlApplicationContext)进行对象的创建

当scope为prototype时,就是在获取对象时(getBean方法)进行创建

如何证明?我们在person的无参构造中加一个控制台输出

先指定scope为singleton,调试一下:

这次指定scope为prototype,调试一下:

如上,当执行完创建工厂的代码时,控制台没有creat person的字样,但再往下看:

当执行完getBean方法后,出现了person无参构造这个打印语句

注:若scope为singleton,但还是想在获得对象时进行对象创建

则在bean标签中加一个lazy-init属性并且指定为true

2.初始化阶段:

Spring工厂创建完对象后,会调用初始化方法。该初始化方法是程序员提供,Spring工厂进行调用。那么如何提供初始化方法?有两种方式

方式一:InitializationBean接口

创建一个product类,实现initialization接口,并且实现其中的方法afterPropertiesSet

其实看这个方法的名字就知道,该方法的执行时期就是在property标签的set注入执行完毕后进行

下面进行文件配置:

方式二.在对象中提供普通的初始化方法,不实现接口

文件配置:

结果:

细节分析

若一个对象既实现类InitializationBean接口,又写了自己的初始化方法

那么就是先执行接口的方法,再执行自己的方法

如果还有property标签进行注入

那么就先注入,再初始化

初始化操作的意义

一般用在资源初始化中:数据库,IO,网络等

3.销毁阶段

Spring工厂在销毁之前,会调用对象的销毁方法,完成销毁操作

Spring何时销毁对象?

在调用ctx.close方法之后进行

如何销毁?

程序员定义销毁方法,Spring调用

方式一:实现DisposiableBean接口的destroy方法

文件配置:

效果:

为什么调用不了close方法呢?因为编译阶段不知道ctx的具体类型,不知道是classpathxmlapplicationcontext调用的还是webxmlapplicationcontext调用的,所以要向下转型,进行强制类型转换:

方式二:不实现接口,提供普通的销毁方法

细节分析

注意:销毁操作只适用于scope=singleton

销毁操作主要是指资源释放的操作,比如io,connection等

十一.配置文件参数化

指的是把Spring配置文件中,需要经常进行修改的字符串信息,转移到一个更小的配置文件中。规定此配置文件就是.properties文件。

有需要经常修改的字符串吗?当然有,就比如之前讲到的connection的创建,进行依赖注入,那些信息就很可能要修改(比如要换一个数据库)

1.好处

将进场需要修改的字符串转移到小的配置文件中,更利于修改,在改动的同时不会影响Spring配置文件中的其他内容

2.开发步骤

还是使用connection举例

提供小配置文件

我们创建一个db.properties文件

也是key value模式,key可以随便起名

将Spring配置文件与小配置文件进行整合

context:property-placeholder标签,表示读取小配置文件,location属性定义了小配置文件的路径。其中,classpath是Spring配置文件中特有的关键字,代表了target目录下的classes目录。

maven项目:开发时,java和resource目录是两个目录,但是编译后就合二为一了。如何证明?target目录存放的就是编译后的文件,打开就可以看到classes目录下面就有之前java和resource目录下的所有.class文件

将字符串填充到配置文件中:

"${key}"key就是小配置文件中的key

十二.自定义类型转换器

1.什么是类型转换器

在person类中,id是int类型,而Spring配置文件也是文件,它里面的内容就应该是字符串,那它怎么就把字符串赋值给了int类型呢?这是因为Spring中内置了类型转换器Converter,并且借助接口实现(为啥是接口?因为字符串要转换成不同的类型)

但是像date类型,每个地区的人的习惯性写法不同,所以Spring就可能无法将日期字符串转化成标准的Date格式(后面会讲为什么是可能)。那该怎么办?这就要我们程序员自定义类型转换器了

2.自定义类型转换器

创建一个Converter包,Person类

再写一个converter接口的实现类

Converter是一个泛型接口,见括号中的第一个表示原始类型,第二个表示要转换成什么类型

接下来我们就要去实现convert方法,这个方法的参数就是Spring配置文件中要被转换的那个字符串

最后在Spring配置文件中配置

首先要将自己写的类型转换器创建出来,然后要在Spring中进行注册。如何注册?

Spring中提供了一个类ConverterFactoryBean,它里面存放的就是各种类型转换器,是以Set集合存储的

所以要想使用自己的类型转换器,就要将自己写的类型转换器存放到set集合中,就如上所示。这样,就能将字符串转化成Date类型啦

3.细节分析

yyyy-MM-dd

它是MydateConverter的依赖项,所以可以对它进行依赖注入,也就是将它作为成员变量进行配置,后需要想修改格式,只需要修改Spring文件即可,就不用重新编译部署,就可以解耦合

为ConverterFactoryBean设标签

要注意id值必须为converterService,否则注册类型转换器不成功

Spring其实内置了日期的类型转换器

但它要求日期格式必须为:四位/二位/二位,否则无法自动转换

十三.后置处理bean

1.Spring创建对象的流程

1.反射调用构造方法

2.DI(注入)

3.InitializingBean的afterPropertySet方法对对象进行初始化

4.init-method="myInit",自定义的初始化方法

学到这里,我们就要再加一个BeanPostProcessor接口,他就是对Spring工厂所创建的对象进行再加工(就像苹果从果园中生长出来后没有直接到顾客手里,而是进行了再加工,提高了品质)

该接口中有两个方法

一个是Before,表示在调用InitializingBean接口的方法之前进行,一个是After,表示在调用了自定义的初始化方法之后进行

2.开发步骤

我们准备一个beanPost包和Category类

进行文件配置:

然后创建一个MyBeanPostProcessor类,实现BeanPostProcessor接口

我们没有实现这两个方法,但是没有报错,这是因为这两个方法是default,表示接口的默认实现

我们的目的是将name属性从小红改为小明。那该如何实现这两个方法呢?如下:

在实际开发中,很少会进行初始化操作,所以上面这两个方法实现一个即可,一般是实现after方法,另一个就返回bean。

最后进行文件配置

效果:

运行后竟然报错了!这是我们之前写的类型转换器不能转换成Category类。这是啥错误?

仔细看这个配置文件,里面有好多个bean标签,最后一个bean标签就是在创建beanPostProcessor的实现类,事实上,同一个配置文件中的对象都要调用BeanPostProcessor接口的方法,即下面我们重写的这个方法:

注意这个bean,这个bean可不是单单是Category对象,而将会是同一个配置文件中的所有对象,所以在话蓝线的这一句就会出现类型转换异常。那么该如何解决此问题?如下:

首先用instanceof判断一下是否是Category类,如果是才能进行下面的修改操作,不是就直接返回,返回的时候也是直接返回bean对象即可

所以一定要注意:​​​​​​​beanPostProcessor会对Spring文件中的所有对象进行加工,所以一定要进行类型匹配的判断。

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

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

相关文章

游戏测试之常见控制技能(下)

备注:未经博主允许禁止转载 个人笔记(整理不易,有帮助,收藏点赞评论,爱你们!!!你的支持是我写作的动力) 笔记目录:学习笔记目录_pytest和unittest、airtest_w…

Linux--Linux常用命令

Linux常用命令 前言Linux命令格式命令讲解1、ls:查看当前目录下所有的内容语法:ls[-al][dir]2、pwd: 查看当前所在目录3、cd : 切换目录4、touch[文件名] : 如果文件不存在新建文件5、mkdir: 创建目录6、rm: 删除指定文件7、rmdir: 删除空目录8、cat:用于显示文件内容9、m…

vue3图片展示实战

首先得有一个vue3项目 教程: vue3项目搭建 我测试存在两种方式可以将本地图片进行展示到页面 public文件夹下可以直接导入src下的asset文件夹下得图片需要在 script 标签内声明再导入网页图片不可导入,应该是存在一种限制 1,创建文件demo1I…

MyCat 数据库中间件

一、介绍 1、单数据库进行数据存储的问题: IO瓶颈:热点数据太多,数据库缓存不足以容纳这些热点数据,产生大量磁盘IO,效率较低。 CPU瓶颈:排序、分组、连接查询、聚合统计等SQL会耗费大量的CPU资源。 2、…

volatility内存取证

记录一道volatility内存取证的题目,第一次遇到,现场把环境搞出来,现记录一些操作指令。 一、安装volatility3 1、新建一个kali虚拟机 新建的过程不再赘述。 2、下载volatility3 GitHub - volatilityfoundation/volatility3: Volatility …

Spring Cloud 运维篇1——Jenkins CI/CD 持续集成部署

Jenkins 1、Jenkins是什么? Jenkins 是一款开源 CI/CD 软件,用于自动化各种任务,包括构建、测试和部署软件。 Jenkins 支持各种运行方式,可通过系统包、Docker 或者一个独立的 Java 程序。 Jenkins Docker Compose持续集成流…

政企版 WPS Pro 专业版注册安装教程

政企版 WPS Pro 专业版安装及激活步骤 第 1 步:下载压缩包(内含注册码)【无解压密码】。 第 2 步:解压缩后,运行 exe 文件,默认步骤安装即可。 第 3 步:安装完成后,新建一个 Word …

Mysql学习大纲

文章目录 整体大纲总结 整体大纲 大纲 MySQL在金融互联网行业的企业级安装部署mysql启动关闭原理和实战,及常见错误排查 花钱9.9 订阅了专栏MySQL字符集和校对规则史上最详细的Mysql用户权原理和实战,生产案例InnoDB引擎原理和实战,通俗易懂…

MySQL如何避免全表扫描?

MySQL如何避免全表扫描? 这篇文章解释了何时以及为什么MySQL会执行全表扫描来解析查询,以及如何避免在大型表上进行不必要的全表扫描。 何时会发生全表扫描 MySQL使用全表扫描(在EXPLAIN输出中的type列显示为ALL)来解析查询的几…

web--弱口令安全

字典(一种是产品初始化的密码,一种是改变的密码 对爆破密码进行加密 先这个 对账号和密码同时爆破 设置两个要用这个模式 ssh,rdp远程终端 linux的用户名为root,windows为administrator 这就被爆破了 zip,word文件猜解

kafka实验部署

一、前期准备 二、kafka实验 在zookeeper后继续进行操作 2.1 为ndoe1、node2、node3作出部署 2.1.1 解压kafka压缩包(node1举例) 2.1.2 操作 将解压后的kafka移动到kafka,进入到kafka下的config中,复制文件 2.1.2.1 编辑server.pr…

7. Spring Boot 创建与使用

经过前面的六篇文章,Spring Framework的知识终于大致讲完了,但是Spring AOP还没提到,个人认为Spring AOP更适合放在Spring MVC之后再讲解,而讲解Spring MVC前先学习Spring Boot的目的也是为了在学习Spring MVC的时候直接使用Sprin…