在前面博客中提到容器启动获得BeanDefinition对象中有一个scope 属性。该属性控制着bean对象的作用域。本章节介绍Bean的作用域及生命周期,了解bean是怎么来的又怎么没的。
一、Bean的作用域
在Bean容器启动会读取bean的xml配置文件,然后将xml中每个bean元素分别转换成BeanDefinition对象。在BeanDefinition对象中有scope 属性,就是它控制着bean的作用域。
Spring框架支持5种作用域,有三种作用域是当开发者使用基于web的ApplicationContext的时候才生效的。下面就是Spring直接支持的作用域了,当然开发者也可以自己定制作用域。
作用域 |
描述 |
单例(singleton) |
(默认)每一个Spring IoC容器都拥有唯一的一个实例对象 |
原型(prototype) |
一个Bean定义,任意多个对象 |
请求(request) |
一个HTTP请求会产生一个Bean对象,也就是说,每一个HTTP请求都有自己的Bean实例。只在基于web的Spring ApplicationContext中可用 |
会话(session) |
限定一个Bean的作用域为HTTPsession的生命周期。同样,只有基于web的Spring ApplicationContext才能使用 |
全局会话(global session) |
限定一个Bean的作用域为全局HTTPSession的生命周期。通常用于门户网站场景,同样,只有基于web的Spring ApplicationContext可用 |
我们可以以XMLInstance类为基础演示一下singleton和prototype作用域。
这里使用通过BeanFactory的getBean方法获取两次bean对象。
XMLInstance instance=(XMLInstance)factory.getBean("xmlinstance"); instance.setName("123"); instance.Breath(); instance=(XMLInstance)factory.getBean("xmlinstance"); instance.Breath();
如果我们采用bean默认的作用域singleton,如下配置,则两个getbean获取的对象是一致的。
<bean id="xmlinstance" class="com.demo.model.XMLInstance" scope="singleton">
<property name="air" ref="CleanAir"></property>
<property name="name" value="abc"></property>
</bean>
输出结果: Name:123;Air:CleanAir Name:123;Air:CleanAir
如果我们采用bean默认的作用域singleton,如下配置,则两个getbean获取的对象是不一致的。
<bean id="xmlinstance" class="com.demo.model.XMLInstance" scope="prototype">
<property name="air" ref="CleanAir"></property>
<property name="name" value="abc"></property>
</bean>
输出结果: Name:123;Air:CleanAir Name:abc;Air:CleanAir
二、Bean的生命周期
前面章节介绍了bean容器以及bean的配置与注入,本章节学习bean的生命周期,了解bean是怎么来的又是怎么没的。
package com.demo.model; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; public class UserBean implements BeanNameAware,BeanFactoryAware,InitializingBean,DisposableBean,ApplicationContextAware { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; System.out.println("set方法被调用"); } public UserBean() { System.out.println("UserBean类构造方法"); } public void setBeanName(String name) { System.out.println("BeanNameAware被调用"); } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("BeanFactoryAware被调用"); } public void afterPropertiesSet() throws Exception { System.out.println("InitializingBean被调用"); } public void destroy() throws Exception { System.out.println("DisposableBean被调用"); } //自定义的初始化函数 public void myInit() { System.out.println("myInit被调用"); } //自定义的销毁方法 public void myDestroy() { System.out.println("myDestroy被调用"); } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("setApplicationContext被调用"); } }
定义了后置处理器CusBeanPostProcessor 实现了BeanPostProcessor 接口。
package com.demo.model; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class CusBeanPostProcessor implements BeanPostProcessor { public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization被调用"); return bean; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessAfterInitialization被调用"); return bean; } }
在xml中配置bean和BeanPostProcessor。
<bean id="user" class="com.demo.model.UserBean" destroy-method="myDestroy" init-method="myInit"> <property name="name" value="abc"></property> </bean> <bean id="postProcessor" class="com.demo.model.CusBeanPostProcessor" />
测试:
ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"}); BeanFactory factory=context; UserBean user=(UserBean)context.getBean("user"); ((ClassPathXmlApplicationContext)context).close();
输出结果:
UserBean类构造方法
set方法被调用
BeanNameAware被调用
BeanFactoryAware被调用
setApplicationContext被调用
postProcessBeforeInitialization被调用
InitializingBean被调用
myInit被调用
postProcessAfterInitialization被调用
DisposableBean被调用
myDestroy被调用
原文:https://www.cnblogs.com/5ishare/p/9532057.html