1、本篇博客的背景和目的
目前我本人正在学习SpringFramework的知识,这也是这个专栏的主题。我前面的几篇博文中,简单的认识了一下SpringFramework,记录了SpringFramework的环境搭建,记录了SpringIOC如何加载配置文件,记录了SpringIOC三种Bean对象的实例化方法。还记录了SpringIOC手动装配(注入)的方法之一:set方法注入。还有另外三个不太常用的SpringIOC手动注入的方法。其实目前大部分都使用的是自动注入的方法,手动注入使用的不多。就算是使用手动注入的方法,使用的主流也是:set方法注入。自动注入的方法主要是使用两个注解,@Autowired注解或者是@Resource注解。两个注解我都记录到了。还记录了如何使用SpringIOC扫描器。本篇博客我记录一下SpringIOC中Bean对象的作用域和生命周期。
2、我的上一篇博文
3、两种类型的作用域
我在前面的博文中不止一次的记录过,默认情况下,我们从Spring容器中拿到的拿到的对象都是单例的,可以说是单例作用域。也就是说我们每次拿到的都是同一个对象。所以,有些类是不能交给Spring容器管理的,比如用户类。
但是:有默认情况,就有非默认情况。这样就有了两种情况或者说是两种作用域。
两种作用域分别是:单例作用域和原型作用域。
单例作用域:我们第一次取得时候,都会先将生成的对象放入单例缓存池中,然后每次使用的时候就从单例缓存池中取出来对应的对象就可以。这明显就是每一次取得都是同一个对象。
原型作用域:我们每一次实例化注入一个对象的时候,都是新实例化出来的;也就是说:每一次拿到的对象都是不一样的,每一次都是new出来的。
4、单例作用域和bean标签新属性lazy-init
下面看一张图,介绍bean标签的一个新属性lazy-init:
可以看到,bean3设置了一个 lazy-init属性;这个属性的作用就是当SpringIOC容器刚启动的时候,不会立刻把这个对象实例化并放入单例缓存池中,只有当程序运行并要使用的时候,才会放入单例缓存池中;这也称为惰性初始化或者是懒加载。
SpringIOC默认的就是单例作用域,那么什么样的类适用于这种单例作用域呢?我前面应该解释过了,像是Controller层的处理请求的类,Service层进行业务逻辑处理的类等,可以使用单例作用域。这里我粘贴一张截图:
5、原型作用域和bean标签的新属性scope
我还是先粘贴一张图片:
bean标签有一个 scope属性,如果这个属性的值是 singleton,那么就表示这个对象是单例模式实例化的,早晚都要缓存到单例缓存池中的,即每一次实例化取到的都是同一个对象;
如果scope属性的值是 prototype,那就表示是 原型模式,那么每一次请求都会返回一个新的对象,并且不会进入单例缓存池中;
默认情况下就是单例模式(单例作用域),单例模式下,当我们在Main方法下测试的时候,拿到的两个对象地址是一样的;
如果设置成了原型作用域,那么我们在Main方法中测试的时候,拿到的两个对象,地址是不一样的;
这里我就不写代码演示了,比较的简单,包括那个 lazy-init属性,我也不演示了;
6、Bean对象的生命周期
先放一下图片:
我们先概括的将Bean对象的生命周期分为四个阶段:定义,初始化,使用,销毁。
首先是定义和初始化:
上面图片中的两种方法其实是显示的让我们看到Bean对象是什么时候实例化的;
然后是使用:
Bean的使用就比较简单啦,在前面的笔记中都是一直在使用的两个接口:BeanFactory或者是ApplicationContext
最后是销毁:
下面我就具体的解释一些整个Bean的整个生命周期:
Bean的生命周期分为四个阶段:Bean的定义,Bean的初始化,Bean的使用,Bean的销毁;
Bean的定义就是我们在XML中写的bean标签,或者使用扫描器的方法,给类加注解。
Bean的初始化,这个就是Spring容器加载后,默认随即实例化Bean
Bean的使用,我们常用的就是 getBean(" id值 ");
Bean的销毁:设置bean标签的destroy-method属性或者像上图一样,使用
AbstractApplicationContext接口加载完配置文件以后调用close()方法;也就是SpringIOC容器关闭的时候,Bean对象才会销毁;
在默认情况下,Spring容器中加载的Bean对象 都是单例的;也就是Spring容器在启动时会实例化Bean对象,并将对象设置到单例缓存池中,下次获取的时候就可以直接从单例缓存池中获取;
而原型作用域:每次请求都会重新创建一个新的对象,不会设置到缓存池中;
下面总结记录一下本篇博文bean标签中的一些属性:
1、lazy-init=" true或者是false" 这个属性是懒加载,默认是false。
如果值为true,则表示容器在启动的时候,不会立刻就实例化Bean对象,
而是在程序调用的时候再实例化Bean对象;如果是false,那表示,
容器启动以后,随即就实例化Bean对象
2、init-method=" 对应Bean类中的一个方法名",这个属性表示只要这个bean
对象被实例化了,就可以调用这个方法。这个方法需要写在对应的类中,
作为public方法;
3、destroy-method=" 对应Bean类中的一个方法名" 这个属性跟 init-method属性是类似 的, 我就不解释了,上面图片里面也有;
4、scope=" " 这个属性值有两个,分别是singleton和prototype。用来设定这个Bean对象是单例作用域还是原型作用域。