Spring bean的作用域以及生命周期

一、request与session的区别

request简介

request范围较小一些,只是一个请求。

request对象的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请求完毕之后,request里边的内容也将被释放点 。

简单说就是你在页面上的一个操作,request.getParameter()就是从上一个页面中的url、form中获取参数。

但如果一个request涉及多个类,后面还要取参数,可以用request.setAttribute()和request.getAttribute()。

但是当结果输出之后,request就结束了。

session简介

session可以跨越很多页面。
而session的生命周期也是针对一个客户端,但是却是在别人设置的会话周期内(一般是20-30分钟),session里边的内容将一直存在,即便关闭了这个客户端浏览器 session也不一定会马上释放掉的。

可以理解是客户端同一个IE窗口发出的多个请求。

这之间都可以传递参数,比如很多网站的用户登录都用到了。

两者区别

request占用资源比较少,安全性也比较高,可是相对来说缺乏持续性。

session则相对来说对资源的消耗会大点,安全性相对来说也会稍微低点,可是它能实现比如会话跟踪技术。

如果可以使用request的情况下,尽量使用request 因为相对于服务器来说资源的消耗还是比较重要的。

在传递页面过程中request传递到下一页面就不能再传递了,而sesison却不如此,即request仅限于2个相邻的页面

每按一个网页上的一个链接就是一个新的request,当服务器返回给浏览器一个response时,request就结束了,此时保存在request中的对象就不存在了,

但是当你用一个浏器连到服务器上时application-server会新开一个session给你,当连接超时或浏览器关闭时session才销毁。

所以说作用的范围是不一样,session也就可以跟踪用户的状态。

二、Spring bean的作用域

Spring 3中为Bean定义了5中作用域,分别为singleton(单例)、prototype(原型)、request、session和global session,5种作用域说明如下:

1.singleton

单例模式,Spring IoC容器中只会存在一个共享的Bean实例,无论有多少个Bean引用它,始终指向同一对象。Singleton作用域是Spring中的缺省作用域,也可以显示的将Bean定义为singleton模式,配置为:

<bean id="userDao" class="com.stonegeek.UserDaoImpl" scope="singleton"/>

2.prototype

原型模式,每次通过Spring容器获取prototype定义的bean时,容器都将创建一个新的Bean实例,每个Bean实例都有自己的属性和状态,而singleton全局只有一个对象。根据经验,对有状态的bean使用prototype作用域,而对无状态的bean使用singleton作用域。

<bean id="userDao" class="com.stonegeek.UserDaoImpl" scope="prototype"/>

3.request

针对每一次Http请求,Spring容器根据该bean的定义创建一个全新的实例,且该实例仅在当前Http请求内有效,而其它请求无法看到当前请求中状态的变化,当当前Http请求结束,该bean实例也将会被销毁。

第一步:在web应用的xml文件中声明ContextListener
<web-app>
 ...
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
 ...
</web-app>
第二步:配置scope即可
<bean id="loginAction" class="com.stonegeek.Login" scope="request"/>

4.session

同Http请求相同,每一次session请求创建新的实例,而不同的实例之间不共享属性,且实例仅在自己的session请求内有效,请求结束,则实例将被销毁。

省略web.xml中的声明
<bean id="userPreference" class="com.stonegeek.UserPreference" scope="session"/>  

5.global Session

相对于session,此session时全局的,在一个全局的Http Session中,容器会返回该Bean的同一个实例,仅在使用portlet context时有效。

省略web.xml中的声明
<bean id="userPreference" class="com.stonegeek.UserPreference" scope="global session"/>  

三、Spring bean的生命周期与初始化过程

先区分一下Spring bean的实例化和初始化两个阶段的主要作用:

实例化:
实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中

初始化:
初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性

执行过程

1.(实例化)执行bean的构造器

2.为bean注入属性

  • 调用BeanNameAware的setBeanName方法
  • 调用BeanFactoryAware的setBeanFactory方法

3.(初始化)

  • 调用InitializingBean的afterPropertiesSet方法
  • 调用自身的init-method属性指定的初始化方法

4.执行正常调用

5.销毁

  • 调用DiposibleBean的destory方法
  • 调用的destroy-method属性指定的销毁方法

1.BeanPostProcessor接口(Spring的后置处理器)

如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。

当然,此接口有的两个方法postProcessBeforeInitialization方法postProcessAfterInitialization方法主要作用于初始化前后,

2.InstantiationAwareBeanPostProcessor接口

InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

3.BeanFactoryPostProcessor接口

Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义多个BeanFactoryPostProcessor,通过设置'order'属性来确定各个BeanFactoryPostProcessor执行顺序。

注册一个BeanFactoryPostProcessor实例需要定义一个Java类来实现BeanFactoryPostProcessor接口,并重写该接口的postProcessorBeanFactory方法。通过beanFactory可以获取bean的定义信息,并可以修改bean的定义信息。这点是和BeanPostProcessor最大区别

4.bean自身的方法

这个包括了Bean本身调用的方法和通过配置文件中的init-method和destroy-method指定的方法

5.bean级生命周期接口方法

这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法

(1)BeanNameAware接口

就一个方法setBeanName(String name)

设定bean的名字

(2)BeanFactoryAware接口

就一个方法setFactory(BeanFactory factory)

注入一个beanfactory

(3)InitializingBean

InitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候会执行该方法。

(4)DiposableBean

DisposableBean接口只提供了destroy()方法。在销毁bean时,会调用此方法

posted @ 2018-07-22 18:09  StoneGeek  阅读(650)  评论(0编辑  收藏  举报