工厂Bean
spring里有两种不同的bean
那么如果我们需要应该如何去做?
传统的,我们展示定义的bean类型就是自己的返回类型
我们可以看到,最终获得的还是MyBean对象
但是工厂bean可以让我们获得不同的对象
我们添加一个course测试类
我们现在希望创建newmybean对象的时候,这个类型是course的对象
如何做?
实现工厂bean的接口
实现接口和方法后
此时我们通过spring创建的“newmybean”对象就是course类型的了
测试
报错提示类型不匹配
因为现在我们的newmybean已经是course类型的对象了,但是我们现在接收还是用的newmybean类型
更改
成功
并且cname里面是我们重写的工厂bean的方法里设置的值
bean的作用域
就是bean起作用的范围
而且可以设置spring创建的bean对象是单实例还是多实例
单实例:bean只创建一个对象,被反复拿过来使用
多实例:bean每次使用getBean方法都创造一个新的对象
如何控制我们的bean是单实例还是多实例?(以book类为例)
此时我们看看默认的情况下,我们的book1和book2是不是同一个东西
是一个
那我们有没有办法让他们不是一个
在bean标签里使用scope属性
默认值单实例
现在修改为多实例再进行测试
现在已经不一样了
单实例与多实例的区别
创建对象的时机不同
bean的生命周期
bean对象的生死消亡过程是什么样的?
我们可以自己尝试展示写着以下
我们在order里面自己写一下这五步
此时我们怎么让bean执行我们的initMethod方法呢?
在bean标签里使用init属性,让他在初始化的时候执行对应方法
标签里填写我们的方法名称
我们都是在测试类里使用bean对象的,所以第四步在使用的时候有
最后一步进行销毁
也要在bean标签里加属性
并且在单元测试里进行对bean的手动销毁
因为Application这个类里面没有close方法,但是它的子接口classpath里面有这个实现类的方法,所以要先进行强制转换
测试成功
但是其实真正的bean生命周期还包含其他很重要的两步
bean的后置处理器
我们看到在初始化前后都要把bean实例传递给后置处理器
什么是后置处理器,它是干什么的?
Bean 后置处理器允许在调用初始化方法前后对Bean 进行额外的处理。 BeanPostProcessor 接口定义回调方法,你可以实现该方法来提供自己的实例化逻辑,依赖解析逻辑等
可以通过判断有没有传递给后置处理器来判断有没有实例化成功(个人理解)
如何观测?——尝试自己加过程
创建后置处理器,实现对应的接口,重写方法
在xml文件里配置后置处理器
此时,在加载配置文件的时候,把每个bean标签里的对象都加载了,但是现在我们的mybeanpost里面重写了后置处理器的方法,spring就会把mybeanpost当作后置处理器,每次实例化每一个bean对象之前和之后都执行后置处理器里的方法
测试成功
bean的自动装配
什么是自动装配?
比如之前我们在需要在property标签里把对象属性或者其他属性进行注入,但是现在有了自动装配,如果有一个bean对象的名字或者类型是正正好好符合另外一个bean需要注入的属性,此时就可以通过标签属性进行自动装配
现在我们需要向emp中自动注入对象dept这个属性
传统方式——通过外部注入
测试成功:
自动装配注入
根据属性名称注入
此时,根据属性名注入,检测到emp类里需要一个Dept类型的dept对象,检索所有的bean标签id有没有为dept的,如果有,就注入对应的id的bean标签所指的class类
测试成功:
根据属性类型注入
此时,根据属性类型注入,检测到emp类里需要一个Dept类型的dept对象,检索所有的bean标签的class有没有相对应的类型,如果有,就把这个类型的对象注入到emp的属性中
测试成功:
注意此时相同类型的bean不能设置多个
由于此时是根据类型注入,但是此时同类型的bean有多个,就不能这样子实现了
管理外部属性文件
以加载数据库连接池文件为例子
先加入德鲁伊数据库连接池的jar包
传统的在xml文件里进行数据库连接
都是以前玩剩下的了
使用外部文件文件进行数据库连接
先新建外部文件
格式为
把外部属性文件注入——使用context名称空间
xml文件内书写格式
value填写注入的外部属性文件地址
原本的value里填写${属性文件左边的key},就可以完成外部文件注入了
以后如果想对于数据库进行更改,只需要更改外部文件,非常方便