Bean的完整生命周期经历了各类方法调用,这些方法能够划分为如下几类:spring
生命周期缓存
建立 ----> 初始化 ---> 销毁app
1. 实例化对象ide
2. setter注入,执行Bean的属性依赖注入函数
3. BeanNameAware的setBeanName(), 若是实现该接口,则执行其setBeanName 方法post
4.BeanFactoryAware的setBeanFactory(), 若是实现该接口,则执行其setBeanFactory方法测试
5. BeanPostProcessor的processBeforeInitialization(),若是有关联的processor,则在Bean初始化以前都会执行这个实例的processBeforeInitialization() 方法spa
综上:3d
// 后置处理器 @Component public class MyBeanPostProcessor implements BeanPostProcessor { /** * 执行自定义init方法以前处理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println( "3.[BeanPostProcessor] ---> postProcessBeforeInitialization 执行init方法[以前]处理") ; return bean; } /** * 执行自定义init方法以后处理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println( "5.[BeanPostProcessor] ---> postProcessAfterInitialization 执行init方法[以后]处理") ; return bean; } }
6. InitializingBean的afterPropertiesSet(), 若是实现了该接口,则执行其afterPropertiesSet()方法。Bean定义文件中定义init-method日志
7.BeanPostProcessors的processAfterInitialization(),若是有关联的processor,则在Bean初始化以前都会执行这个实例的processAfterInitialization()方法
8.DisposeablebBean的 destory(),在容器关闭时,若是Bean实现了这个接口,则执行他的destory()方法
9. Bean定义文件中定义destroy-method,在容器关闭时,能够在Bean定义文件中使用“destory-method”定义的方法
注:
1. 单例默认时在容器被加载时候会初始化
2. 多例在每次获取Bean的对象时候才会去初始化
bean 初始化 指的就是对象已经建立里面全部的set方法都已经执行完毕了。 指定方法执行
@Bean(initMethod , destory) 指定初始化和销毁方法 同时在bean中建立这两个方法
init是在构造方法以前仍是以后执行? 无参构造! 对象先建立完成后才进行初始化!因此先执行无参构造函数!
补充到上面的过程:
Bean的建立(执行构造函数) --> 初始化(自定义init方法) --> 销毁
调用close() 方法销毁单例对象
注意:IOC容器使用Map结合存储对象,clear() 清除对象
看源码:
进入查看:
继续点击查看:
看第一个:
持续跟进后就是 集合的 clear 方法了
咱们能够经过实现某些类 去进行初始化的操做!
开发使用的方式:
方法一: 经过@Bean指定init-method 和 destory-method
方法二: 经过让Bean实现InitializingBean(定义初始化逻辑), DisposableBean(定义销毁逻辑)
方法三: 使用JSR250(Java规范,不是Spring的): @PostConstruct: 在Bean建立完成而且赋值完成,来执行初始化方法。 @PreDestory: 在容器销毁Bean以前通知咱们进行清理工做
方法二:
Bean:
@Component public class LifeBean implements InitializingBean, DisposableBean { //构造函数 public LifeBean() { System.out.println("LifeBean Constructor"); } /** 接口InitializingBean的方法 * //解释 对象有建立 确定也有给属相赋值的过程!,对象赋值完毕之后才执行该方法 即: (afterPropertiesSet)中文:set方法都走完了时候执行该方法 * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { //等同于 @Bean(init =" ") //解释 对象有建立 确定也有给属相赋值的过程!,对象赋值完毕之后才执行该方法 System.out.println("LifeBean ********> 【InitializingBean.afterPropertiesSet】 "); } /** * 接口DisposableBean 的方法 * @throws Exception */ @Override public void destroy() throws Exception { System.out.println("LifeBean ********>【DisposableBean.destroy】"); } }
配置和扫包
@Configuration @ComponentScan("com.toov5.config.beanTest.entity") public class MyConfig { }
启动测试:
public class test { public test(){ } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext("com.toov5.config"); applicationContext1.close(); // System.out.println(applicationContext1); } }
方法三
注解代替了接口:
Bean:
@Component public class LifeBean { //构造函数 public LifeBean() { System.out.println("LifeBean Constructor"); } @PostConstruct public void afterPropertiesSet() throws Exception { //等同于 @Bean(init =" ") //解释 对象有建立 确定也有给属相赋值的过程!,对象赋值完毕之后才执行该方法 System.out.println("LifeBean ********> 【InitializingBean.afterPropertiesSet】 "); } @PreDestroy public void destroy() throws Exception { System.out.println("LifeBean ********>【DisposableBean.destroy】"); } }
效果是同样的:
几个重要的Aware接口:
1. ApplicationContextAware
过滤器中,不可使用注解方式获取Bean对象。 作法: 单独获取上下文ApplicationContext
后置处理器,实现对Bean初始化加强功能
@Component public class MyApplicationContext implements ApplicationContextAware { //开发时候常常作成全局的 进行使用 private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { LifeBean lifeBean = applicationContext.getBean("lifeBean", LifeBean.class); System.out.println("result————————————————————"+lifeBean.toString()); } }
运行后:结果是没问题的
问题: Spring底层中为何可以实现ApplicationContextAware接口,就可以拿到ApplicationContext。
2. BeanNameAware 与 BeanFactoryAware
Bean
@Component public class LifeBean01 implements BeanNameAware, BeanFactoryAware { public LifeBean01() { System.out.println("LifeBean01 对象实例化完成"); } @Override public void setBeanName(String s) { System.out.println("beanName:"+s); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("beanFactory:"+ beanFactory); } }
配置类:
@Configuration @ComponentScan("com.toov5.config.beanTest.entity") public class MyConfig { }
测试:
public class test { public test(){ } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext("com.toov5.config"); applicationContext1.close(); // System.out.println(applicationContext1); } }
IOC容器初始化到哪里独享都是循环遍历getBean方法。
getSingleton(beanName) 先查询缓存有没有,看下以前有没有建立过
Spring Bean生命周期中的后置处理器: BeanPostProcessor接口
从源码能够看到是 能够在 init以前或者以后进行一系列的操做的
加上上面的那几个接口一块儿展现下:
后置处理器,单独处理到别的bean里面去, 其余的bean(Spring 自带的都会走这个方法了)。
init 以前以后,经过后置处理器对bean的初始化进行加强。 能够作bean耗时统计,日志打印等等。
Bean:
@Component public class LifeBean01 implements BeanNameAware, BeanFactoryAware, InitializingBean { public LifeBean01() { System.out.println("1. -----------------》LifeBean01 对象实例化完成"); } @Override public void setBeanName(String s) { System.out.println("2. -----------------》对象beanName:"+s); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("3. -----------------》beanFactory:"+ beanFactory); } @Override public void afterPropertiesSet() throws Exception { System.out.println("5. -----------------》 bean init 方法执行"); } }
后置处理器:
// 后置处理器 @Component public class MyBeanPostProcessor implements BeanPostProcessor{ /** * 执行自定义init方法以前处理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println( beanName + "==========> 执行init方法[以前]处理"); return bean; } /** * 执行自定义init方法以后处理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(beanName +"==========>执行init方法[以后]处理"); return bean; } }
配置类:
@Configuration @ComponentScan("com.toov5.config.beanTest.entity") public class MyConfig { }
测试:
public class test { public test(){ } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext("com.toov5.config"); // applicationContext1.close(); // System.out.println(applicationContext1); } }
结果:
生命周期流程图:
描述:
1.实例化对象 (能够反射, 能够new)
2. 给对象属性赋值
3. 检查是否有Aware依赖,若是有上述的哪些,就进行执行。
总结: 重点无非就是 Aware 和 后置处理器
从源码中看 setApplicationContext() 方法是在前置获取的。 经过postProcessBefore前置,里面的默认方法获取到上下文对象。
总结:
后置处理器:
@Component public class LifeBean implements BeanNameAware, BeanFactoryAware , InitializingBean, DisposableBean { @Override public void setBeanName(String s) { System.out.println("1.[BeanNameAware] ---> setBeanName"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("2.[BeanFactoryAware] ---> setBeanFactory"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("4.[InitializingBean] ---> afterPropertiesSet"); } @Override public void destroy() throws Exception { System.out.println("6.[DisposableBean] ---> distory" ); } }
Bean:
// 后置处理器 @Component public class MyBeanPostProcessor implements BeanPostProcessor { /** * 执行自定义init方法以前处理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println( "3.[BeanPostProcessor] ---> postProcessBeforeInitialization 执行init方法[以前]处理") ; return bean; } /** * 执行自定义init方法以后处理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println( "5.[BeanPostProcessor] ---> postProcessAfterInitialization 执行init方法[以后]处理") ; return bean; } }
配置:
@Configuration @ComponentScan("com.spring.test") public class config { }
测试
public class test { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext(config.class); applicationContext1.close(); } }