javascript
Spring核心——Bean的生命周期
文章目錄
- 序言
- 一:Bean生命周期流程圖
- 二:測(cè)試方法以及步驟
- 1、創(chuàng)建一個(gè)bean
- 2、創(chuàng)建BeanFactoryPostProcessor 的實(shí)現(xiàn)實(shí)例
- 3、創(chuàng)建InstantiationAwareBeanPostProcessorAdapter實(shí)現(xiàn)實(shí)例
- 4、創(chuàng)建BeanPostProcessor實(shí)現(xiàn)實(shí)例
- 5、將實(shí)例注冊(cè)到Spring中
- 6、測(cè)試代碼
- 7、運(yùn)行日志
序言
Bean是Spring框架的核心,無(wú)論我們用的是SpringMVC、SpringBoot、SpringCloud都繞不開(kāi)Bean的構(gòu)造,理解了Bean的生命周期有利于我們更好的了解自己的項(xiàng)目并且可以對(duì)現(xiàn)有的框架做一些擴(kuò)展。
一:Bean生命周期流程圖
首先,看一下Bean整個(gè)生命周期的流程圖,這張圖有利于我們了解整個(gè)過(guò)程中的調(diào)用情況。
原圖:https://www.processon.com/view/link/5e421d84e4b00de9fd84a623
二:測(cè)試方法以及步驟
Spring中有很多繼承于A(yíng)ware中的接口,aware的意思是已知的,所以從這些Aware中我們能從Spring容器獲取到已知的一些信息。
簡(jiǎn)單舉例來(lái)說(shuō),比如我們實(shí)現(xiàn)了ApplicationContextAware,我們就可以從里面獲取到ApplicationContext上下文對(duì)象。
下面通過(guò)簡(jiǎn)單的代碼示例來(lái)模擬bean的生命周期。
1、創(chuàng)建一個(gè)bean
這個(gè)Bean實(shí)現(xiàn)了一下接口:
BeanFactoryAware BeanNameAware BeanClassLoaderAware ResourceLoaderAware MessageSourceAware EnvironmentAware ApplicationContextAware InitializingBean DisposableBeanBean的實(shí)現(xiàn)如下:
public class UserInfo implements BeanFactoryAware,BeanNameAware,BeanClassLoaderAware,ResourceLoaderAware,MessageSourceAware,EnvironmentAware,ApplicationContextAware,InitializingBean,DisposableBean {//用戶(hù)idInteger id;//用戶(hù)名稱(chēng)String name;//用戶(hù)性別String gender;//用戶(hù)年齡String age;//備注String remarks;public UserInfo() {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo構(gòu)造方法");}public void myInit() {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo的myInit()方法");}public void myDestroy() {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo的myDestroy()方法");}public Integer getId() {return id;}public void setId(Integer id) {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo賦值屬性的setId()");this.id = id;}public String getName() {return name;}public void setName(String name) {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo賦值屬性的setName()");this.name = name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender = gender;}public String getAge() {return age;}public void setAge(String age) {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo賦值屬性的setAge()");this.age = age;}public String getRemarks() {return remarks;}public void setRemarks(String remarks) {this.remarks = remarks;}@Overridepublic String toString() {System.out.println(DateUtil.getTimeNow() + "調(diào)用UserInfo賦值屬性的toString()");return DateUtil.getTimeNow() + "UserInfo{" +"id=" + id +", name='" + name + '\'' +", gender='" + gender + '\'' +", age='" + age + '\'' +", remarks='" + remarks + '\'' +'}';}@Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanClassLoaderAware的setBeanClassLoader()");}@Overridepublic void setBeanName(String s) {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanNameAware的setBeanName()");}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println(DateUtil.getTimeNow() + "調(diào)用ApplicationContextAware的setApplicationContext()");//模擬獲取系統(tǒng)運(yùn)行參數(shù)String sysProp = applicationContext.getEnvironment().getProperty("System.id");System.out.println(DateUtil.getTimeNow() + "獲取系統(tǒng)參數(shù)System.id=" + sysProp);}@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanFactoryAware的setBeanFactory()");}@Overridepublic void setEnvironment(Environment environment) {System.out.println(DateUtil.getTimeNow() + "調(diào)用EnvironmentAware的setEnvironment()");System.out.println(DateUtil.getTimeNow() + environment.getProperty("user.dir"));//設(shè)置系統(tǒng)運(yùn)行參數(shù)String sysProp = "springtest";System.out.println(DateUtil.getTimeNow() + "設(shè)置系統(tǒng)參數(shù)System.id=" + sysProp);System.setProperty("System.id", sysProp);}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println(DateUtil.getTimeNow() + "調(diào)用InitializingBean的afterPropertiesSet()");}@Overridepublic void setMessageSource(MessageSource messageSource) {System.out.println(DateUtil.getTimeNow() + "調(diào)用MessageSourceAware的setMessageSource()");}@Overridepublic void setResourceLoader(ResourceLoader resourceLoader) {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanClassLoaderAware的setBeanClassLoader()");}@Overridepublic void destroy() throws Exception {System.out.println(DateUtil.getTimeNow() + "調(diào)用DisposableBean賦值屬性的destroy()");}}2、創(chuàng)建BeanFactoryPostProcessor 的實(shí)現(xiàn)實(shí)例
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {public MyBeanFactoryPostProcessor() {super();System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanFactoryPostProcessor構(gòu)造方法");}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanFactoryPostProcessor的postProcessBeanFactor(),[" + configurableListableBeanFactory + "]");} }3、創(chuàng)建InstantiationAwareBeanPostProcessorAdapter實(shí)現(xiàn)實(shí)例
首先看一下UML圖,了解一下跟BeanPostProcessor的關(guān)系:
然后接著去實(shí)例化InstantiationAwareBeanPostProcessorAdapter
4、創(chuàng)建BeanPostProcessor實(shí)現(xiàn)實(shí)例
public class MyBeanPostProcess implements BeanPostProcessor {public MyBeanPostProcess(){super();System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanPostProcess構(gòu)造方法");}@Overridepublic Object postProcessBeforeInitialization(Object o, String s) throws BeansException {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanPostProcess的postProcessBeforeInitialization(),[" + s + "]");return o;}@Overridepublic Object postProcessAfterInitialization(Object o, String s) throws BeansException {System.out.println(DateUtil.getTimeNow() + "調(diào)用BeanPostProcess的postProcessAfterInitialization(),[" + s + "]");return o;} }5、將實(shí)例注冊(cè)到Spring中
將以上幾個(gè)實(shí)例注冊(cè)到Spring中,然后進(jìn)行測(cè)試
<!-- 注入實(shí)例化的BeanFactoryPostProcessor--><bean class="com.leo.model.MyBeanFactoryPostProcessor"></bean><!-- 注入實(shí)例化的BeanPostProcessor --><bean class="com.leo.model.MyBeanPostProcess"></bean><!-- 注入實(shí)例化的InstantiationAwareBeanPostProcessor --><bean class="com.leo.model.MyInstantiationAwareBeanPostProcessor"></bean><!-- 手動(dòng)定義一個(gè)bean --><bean id="userInfo" name="userInfo2" class="com.leo.model.UserInfo" init-method="myInit" destroy-method="myDestroy"><property name="id" value="1"></property><property name="name" value="張颯"></property><property name="age" value="18"></property></bean>6、測(cè)試代碼
private static final String CLASS_PATH_RESOURCE = "applicationContext-test.xml";@Testpublic void classPathXmlApplicationContextTest() throws InterruptedException {ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(CLASS_PATH_RESOURCE);UserInfo userInfo = (UserInfo) applicationContext.getBean("userInfo");System.out.println(userInfo);TimeUnit.SECONDS.sleep(3);//模擬業(yè)務(wù)運(yùn)行applicationContext.registerShutdownHook();//銷(xiāo)毀容器}7、運(yùn)行日志
[2020-02-24 11:11:35.596] 調(diào)用BeanFactoryPostProcessor構(gòu)造方法 [2020-02-24 11:11:35.644] 調(diào)用BeanFactoryPostProcessor的postProcessBeanFactor(),[org.springframework.beans.factory.support.DefaultListableBeanFactory@4dfa3a9d: defining beans [com.leo.model.MyBeanFactoryPostProcessor#0,com.leo.model.MyBeanPostProcess#0,com.leo.model.MyInstantiationAwareBeanPostProcessor#0,userInfo]; root of factory hierarchy] [2020-02-24 11:11:35.649] 調(diào)用BeanPostProcess構(gòu)造方法 [2020-02-24 11:11:35.650] 調(diào)用InstantiationAwareBeanPostProcessor構(gòu)造方法 [2020-02-24 11:11:35.671] 調(diào)用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation(),[userInfo] [2020-02-24 11:11:35.672] 調(diào)用UserInfo構(gòu)造方法 [2020-02-24 11:11:35.672] 調(diào)用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation(),[userInfo], 返回: true [2020-02-24 11:11:35.734] 調(diào)用InstantiationAwareBeanPostProcessor的postProcessPropertyValues(),[userInfo] [2020-02-24 11:11:35.773] 調(diào)用UserInfo賦值屬性的setId() [2020-02-24 11:11:35.774] 調(diào)用UserInfo賦值屬性的setName() [2020-02-24 11:11:35.774] 調(diào)用UserInfo賦值屬性的setAge() [2020-02-24 11:11:35.775] 調(diào)用BeanNameAware的setBeanName() [2020-02-24 11:11:35.775] 調(diào)用BeanClassLoaderAware的setBeanClassLoader() [2020-02-24 11:11:35.777] 調(diào)用BeanFactoryAware的setBeanFactory() [2020-02-24 11:11:35.779] 調(diào)用EnvironmentAware的setEnvironment() [2020-02-24 11:11:35.780] E:\WorkSpace\Git\spring-framework-learning-example\chapter-4-springmvc-sourcecode-analysis [2020-02-24 11:11:35.780] 設(shè)置系統(tǒng)參數(shù)System.id=springtest [2020-02-24 11:11:35.781] 調(diào)用BeanClassLoaderAware的setBeanClassLoader() [2020-02-24 11:11:35.783] 調(diào)用MessageSourceAware的setMessageSource() [2020-02-24 11:11:35.783] 調(diào)用ApplicationContextAware的setApplicationContext() [2020-02-24 11:11:35.784] 獲取系統(tǒng)參數(shù)System.id=springtest [2020-02-24 11:11:35.785] 調(diào)用BeanPostProcess的postProcessBeforeInitialization(),[userInfo] [2020-02-24 11:11:35.787] 調(diào)用InitializingBean的afterPropertiesSet() [2020-02-24 11:11:35.788] 調(diào)用UserInfo的myInit()方法 [2020-02-24 11:11:35.789] 調(diào)用BeanPostProcess的postProcessAfterInitialization(),[userInfo] [2020-02-24 11:11:35.818] 調(diào)用UserInfo賦值屬性的toString() [2020-02-24 11:11:35.819] UserInfo{id=1, name='張颯', gender='null', age='18', remarks='null'} [2020-02-24 11:11:38.833] 調(diào)用DisposableBean賦值屬性的destroy() [2020-02-24 11:11:38.834] 調(diào)用UserInfo的myDestroy()方法總結(jié)
以上是生活随笔為你收集整理的Spring核心——Bean的生命周期的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 我为什么会焦虑?
- 下一篇: SpringMVC学习(四)——Spri