目录
Bean的作用域
singleton
prototype
request
session
application
websocket
单例作用域和全局作用域的区别
Bean的生命周期
Bean的作用域是指Bean在Spring整个框架中的某种行为模式,比如singleton单例作用域,就表示Bean在整个Spring中只有一份,它是全局共享的,当其他人修改了这个值后,另一个人读取到的就是被修改的值.
Spring容器在初始化一个Bean的实例时,同时会指定该实例的作用域.Spring有六种作用域,最后四种基于Spring MVC生效
· singleton:单例作用域
· prototype:原型作用域
· request:请求作用域
· session:会话作用域
· application:全局作用域
· websocket:HTTP WebSocket作用域
该作用域下的Bean在IoC容器中只存在一个实例:获取Bean(即通过applicationContext.getBean等方法获取)及装配Bean(通过@Autowired注入)都是同一个对象。
场景:通常无状态的Bean使用该作用域,无状态表示Bean对象的属性状态不需要更新
Spring默认选择该作用域
每次对该作用域下的Bean的请求都会创建新的实例:获取Bean(即通过applicationContext.getBean等方法获取)及装配(通过@Autowired注入)都是新的对象实例。
通常有状态的Bean使用该作用域
每次HTTP请求都会创建新的Bean实例,类似于prototype
一次http的请求和响应的共享bean,限定在Spring MVC中使用
在一个http session中,定义一个Bean实例
用户会话的共享bean,比如记录一个用户的登录信息,限定在Spring MVC中使用
在一个http servlet Context中定义一个Bean实例
Web应用的上下文信息,比如记录一个应用的共享信息,限定在Spring MVC中使用
WebSocket的每次会话中,保存了一个Map结构的头信息,将用来包裹客户端消息头。第一 次初始化后,直到WebSocket结束都是同一个Bean,限定在Spring MVC中使用。在一个HTTP WebSocket的生命周期中,定义一个Bean实例
· singleton是Spring Core的作用域;application是Spring MVC中的作用域
· singleton作用于IoC容器,而application作用于Servlet容器
1、实例化Bean(为Bean分配内存空间),类似于new对象
2、设置属性(Bean注入和装配)
3、Bean初始化(表示Bean要初始化很多内容才能使用)
· 实现了各种Aware通知的方法,如BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法;bean实现这些通知接口后,在这个时机就会依次执行Aware通知接口的方法
· 执行BeanPostProcessor初始化前置方法;BeanPostProcessor接口中的一个方法(XXXbeforeXXX)
· 执行@PostConstruct初始化方法,依赖注入操作之后被执行;
· 执行自己制定的init-method方法
· 执行BeanPostProcessor初始化后置方法;BeanPostProcessor接口中的一个方法(XXXafterXXX)
4、使用Bean
5、销毁Bean
代码示例
LifecycleConfig类
package org.lifecycle.config;import org.lifecycle.model.MyBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class LifestyleConfig implements BeanPostProcessor {//如果MyBean类去掉@Service注解,就需要这么写@Bean(initMethod = "myInitMethod", destroyMethod = "destroy2")//initMethod的值,是对象中方法的名称public MyBean bean() {return new MyBean();}@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessor生命周期初始化前置方法");return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("BeanPostProcessor生命周期初始化后置方法");return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);}
}
MyBean类
package org.lifecycle.model;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class MyBean implements BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean {public MyBean() {System.out.println("Bean对象实例化");}@Overridepublic void setBeanName(String s) {System.out.println("BeanNameAware生命周期方法");}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println("BeanFactoryAware生命周期方法");}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println("ApplicationContextAware生命周期方法");}@PostConstructpublic void init() {System.out.println("Bean的初始化方法:@PostConstruct");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("Bean的初始化方法:InitializingBean接口实现");}//初始化方法2public void myInitMethod() {System.out.println("Bean的初始化方法:@Bean(initMethod=本方法名)来制定的初始化");}//销毁方法1@PreDestroypublic void destroy1() {System.out.println("Bean的销毁方法,@PreDestroy");}//销毁方法2@Overridepublic void destroy() throws Exception {System.out.println("Bean的销毁方法,DisposableBean接口实现");}//销毁方法3public void destroy2() {System.out.println("Bean的销毁方法,@Bean(destroyMethod=本方法名)");}
}
启动类
package org.lifecycle;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class App {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("org.lifecycle");//销毁容器,就会执行bean的销毁方法context.close();}
}
通过输出结果,可以完整的观察到Bean对象的生命周期