什么是Bean的生命周期呢?
Bean的生命周期指Bean创建-->初始化-->销毁 的过程
我们可以自定义Bean初始化和销毁方法
容器在bean进行到当前生命周期的时候, 来调用自定义的初始化和销毁方法
早期xml的方式,在<bean>标签里 需要写 init-method destroy-method,指定初始化的方法要做的事以及销毁的时候要做的事,如下图所示:
![758ccbf92087629f5ef08ba66c52c310.png](https://i-blog.csdnimg.cn/blog_migrate/eadf6518feb18d4c077d80d24706c25e.jpeg)
后来可以直接用注解的方式:
单实例Bean的生命周期:
单例Bean的生命周期就是
ioc容器创建的时候,会调用单例bean的构造器以及init方法初始化bean;
ioc容器关闭的时候,调用destory销毁bean。
![33972a685b131de3fe2f6bb66547af85.png](https://i-blog.csdnimg.cn/blog_migrate/e0acfe9a44e1f7c275ca59e8b94be01f.jpeg)
测试:
![2b7e41a6cc3767937ca6a8b3358828d8.png](https://i-blog.csdnimg.cn/blog_migrate/2b10eb03e63571d9965ffbfdc68f3625.jpeg)
如上图所示,单例Bean的生命周期就是 ioc容器创建的时候,会调用单例bean的构造器以及init方法初始化bean;ioc容器关闭的时候,调用destory销毁bean。
多实例Bean的生命周期:
对于多实例的bean,容器只负责初始化, 但不会管理bean, 容器关闭时不会调用销毁方法
可以添加 @Scope("prototype") 来验证
![7657feaa4def7f027db873c5a9c545a6.png](https://i-blog.csdnimg.cn/blog_migrate/5c8885b1c3d510179840211b64b328a1.png)
测试:可以看到Sandy类里写的任何输出都没有
![6e6a4315ca2b603028210a15067bda8b.png](https://i-blog.csdnimg.cn/blog_migrate/1dff6b5feb759e1012e8304ba5081d4d.jpeg)
上述方法都是自己在实体类里写 init() 和 destory()方法。
Spring也有相应的提供Bean的 init() 和 destory() 接口:
init:实现 InitializingBean 接口的 afterPropertiesSet() 方法,当 beanFactory 创建好对象,且把bean所有属性设置好之后,会调这个方法,相当于初始化方法
destory:实现 DisposableBean的destory()方法,当bean销毁时,会把单实例bean进行销毁
![833adf223f60353a89fe9727012d8e05.png](https://i-blog.csdnimg.cn/blog_migrate/c988d8ded90d16557afddb2eb4ed090a.jpeg)
测试类:
![6d99592f607c9155c0c11810fb68dfe2.png](https://i-blog.csdnimg.cn/blog_migrate/1222a7bee241b0b34da187127640dd87.jpeg)
还有一种方式,使用注解:
![2a750ab6c8eeda0141fe65f47d20b6ec.png](https://i-blog.csdnimg.cn/blog_migrate/749d38fbab0f750122d79e99f6a6f9a8.jpeg)
![59080af1d767d54d34d3f9b7851f3323.png](https://i-blog.csdnimg.cn/blog_migrate/9c02619853e5ab25522f1b0e0b6da59d.jpeg)
测试:
![da69b70732bc662bbe74a67b2608fba3.png](https://i-blog.csdnimg.cn/blog_migrate/cbbcbdbfe5a774bd76ca1a49d46c9c81.jpeg)
看下面这段代码:是Bean的生命周期的一段核心代码,具体打个断点就可以找到
![e7d5c0abc9ff2acc9b07899a1348e583.png](https://i-blog.csdnimg.cn/blog_migrate/d2991495b5b1f364888584b553d902b4.jpeg)
Bean生命周期 BeanPostProcessor
在bean初始化之前调用进行拦截,在bean初始化前后进行一些处理工作
使用BeanPostProcessor如何控制Bean的生命周期;
实现BeanPostProcessor的两个接口即可
1, postProcessBeforeInitialization()
2,postProcessAfterInitialization()
实体类SuSan:用注解@PostConstruct标注了 init ,用@PreDestroy 标注了destory 方法
![7f4352d3a3b073b02478bef4544693cc.png](https://i-blog.csdnimg.cn/blog_migrate/5421b0a918e3c054ab011b0bde20efad.png)
空的实体类:和有初始化和销毁方法的SuSan类做对比
![7d48de263fe776daaab9c279729bd7a3.png](https://i-blog.csdnimg.cn/blog_migrate/6699234e0cb6d81c03742025eaa05dfa.png)
实现了 BeanPostProcessor 接口的类 T
![0675ef6566bc1737d3410787e047104d.png](https://i-blog.csdnimg.cn/blog_migrate/d0171db102e85efad1ca3f69a668dac3.png)
然后是配置类:
![36e3712fd34160eb7fb07111f56cb3a9.png](https://i-blog.csdnimg.cn/blog_migrate/3e0775aaec6d016f48ce004a68a5631b.png)
因为我在实体类上标注了 @Component , 在配置类上又标注了@ComponentScan
这样配置类就可以把相应路径下的包里加了 @Component、@Service、@Controller等注解的类自动注入到容器中,所以在配置类里就不用再写对应实体类写方法 然后方法头上加@Bean了。
测试类:
![d0c4e1ca4151d1335e461635983a5495.png](https://i-blog.csdnimg.cn/blog_migrate/ad7ebd763f2bf3bd268ff0b7b977bf7b.png)
![e6e839126970b241de1c6f694f13ab99.png](https://i-blog.csdnimg.cn/blog_migrate/a46665c4edbbdb490a4026429c30fb60.jpeg)
BeanPostProcessor 具体后面文章再做分析