外包网站开发多少钱,wordpress淘宝客单页模板,东营网站建设服务,企业形象设计vi模板接上篇#xff0c;从第八个问题讲起
八.Spring工厂创建复杂对象
1.什么是复杂对象
简单对象就是可以直接new出来的#xff0c;也就是直接调用构造方法创建
所以复杂对象就是不能直接通过调用构造方法创建。就比如JDBC中的Connection
2.三种方法
#xff08;1#xff…接上篇从第八个问题讲起
八.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调用的所以要向下转型进行强制类型转换 方式二不实现接口提供普通的销毁方法 细节分析
注意销毁操作只适用于scopesingleton
销毁操作主要是指资源释放的操作比如ioconnection等
十一.配置文件参数化
指的是把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-methodmyInit自定义的初始化方法
学到这里我们就要再加一个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文件中的所有对象进行加工所以一定要进行类型匹配的判断。