spring中bean的细节
一、bean的细节之三种创建Bean对象的方式
1、第一种方式:使用默认构造函数创建
我们来演示一下
回到我们的service实现类,我们对构造函数跟saveAccount方法做一下修改。
由于我写了一个构造函数,但又没重写默认构造函数,这就代表我们的默认构造函数没有啦。
我们运行发现,果然是出错的,看它报的错误,没有默认构造函数。
2、第二种方式: 使用普通工厂中的方法创建对象(使用某个类中的方法创建对象,并存入spring容器)
我们先把Service实现类,里面的构造函数,String name 参数给去掉。
我们来想一个问题:
我们在实际开发中,有可能会用到一些别人写好的类,那别人写好的类有可能是存在于jar包中的,存在jar包中的类都是字节码文件,都是别人写好的,我们没有办法修改的,那在这种情况下,我们如何使用呢?
这个时候我们的第二种创建bean的方式就出来了。
同样,我们来演示一下
我们创建一个InstanceFactory类。
接着,我们配置Bean对象
我们测试一下,没有问题:
3、第三种方式:使用工厂中的静态方法创建对象(使用某个类中的静态方法创建对象,并存入spring容器)
第三种方式就是第二种方式的延伸,又有一个问题:那如果类中的方法不是普通的方法,是静态方法呢?
这个时候就用到我们的第三种bean创建方式了
同样,我们来演示一下
我们把InstanceFactory类中的方法改成静态的
把第二种方式注上,换第三种
测试一下,没有问题
二、bean的细节之作用范围
bean的作用范围调整
bean标签的scope属性:
作用:用于指定bean的作用范围
取值: 常用的就是单例的和多例的
singleton:单例的(默认值)
prototype:多例的
request:作用于web应用的请求范围
session:作用于web应用的会话范围
global-session:作用于集群环境的会话范围(全局会话范围),当不是集群环境时,它就是session
我们来演示一下singleton 跟 prototype:
1、scope取值singleton。
把之前的给注释上。
接着,我们对main方法里面的代码做一些修改。运行,因为是单例的,所以两个对象是一样的,为true。
2、scope取值prototype。
修改scope取值为多例的prototype
运行main,因为是多例的,所以结果肯定是false。
3、scope取值global-session。
看一张图就懂了
三、bean的细节之生命周期
bean对象的生命周期
单例对象
出生:当容器创建时对象出生
活着:只要容器还在,对象一直活着
死亡:容器销毁,对象消亡
总结:单例对象的生命周期和容器相同
多例对象
出生:当我们使用对象时spring框架为我们创建
活着:对象只要是在使用过程中就一直活着。
死亡:当对象长时间不用,且没有别的对象引用时,由Java的垃圾回收器回收
接着我们来分别演示一下,单例跟多例
1、单例。
我们重写实现类的两个方法。
配置bean
把之前的注释掉
运行main方法,我们发现容器创建了,但是没有销毁。。。。其实容器已经销毁了,只是main方法反应太快了,效果没有出来。
我们修改一下main方法里面的代码,手动销毁容器,效果已经出来了。
2、多例。
我们把bean改成多例。
我们再运行main方法,我们发现对象并没有销毁,因为多例不是随着容器的销毁,而销毁的。