Spring執(zhí)行流程和Bean的生命周期詳解
1、Spring執(zhí)行流程
Spring執(zhí)行流程(Bean執(zhí)行流程):1、在啟動(dòng)類(lèi)中遇到了ApplicationContext的時(shí)候就會(huì)啟動(dòng) Spring 容器 -> 2、根據(jù)容器設(shè)置的配置文件,去找相應(yīng)的配置文件; ->3、如果有base-package,那么就去base-package里循環(huán)找所有的類(lèi),看有沒(méi)有五大類(lèi)注解和方法注解; ->4、 如果有注解,進(jìn)行初始化和屬性依賴(lài)賦值
2、Bean的生命周期(重點(diǎn))
所謂生命周期是指一個(gè)對(duì)象從創(chuàng)建到銷(xiāo)毀的過(guò)程。
Bean的生命周期可分為以下5大部分:
1.實(shí)例化Bean:為Bean分配空間
2.**設(shè)置屬性:**為Bean注入屬性和裝配屬性
3.Bean初始化:
- 實(shí)現(xiàn)各種通知方法:BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法。
- 執(zhí)行前置方法(BeanPostProcessor接口)
- 執(zhí)行初始化方法(設(shè)置了才會(huì)執(zhí)行)
- 注解方式:@PostConstruct,依賴(lài)注入后被執(zhí)行(優(yōu)先級(jí)高,主流方式)
- xml方式:init-method ?法
- 執(zhí)行后置方法(BeanPostProcessor接口)
4.使用Bean
5.銷(xiāo)毀Bean:@PreDestroy、DisposableBean 接??法、destroy-method。
圖示化流程:
偽代碼流程(xml方式):
public class BeanLife implements BeanNameAware, BeanFactoryAware, BeanPostProcessor { /* 各種通知 */ @Override public void setBeanName(String s) { //s 是設(shè)置的Bean名稱(chēng) System.out.println("執(zhí)行了通知:BeanNameAware - > BeanName = "+s); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("執(zhí)行了通知:BeanFactoryAware"); } /* 前置方法 :默認(rèn)情況不會(huì)顯式調(diào)用 */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("執(zhí)行了前置方法:postProcessBeforeInitialization"); return bean; } /* 初始化 */ public void myInit(){ System.out.println("執(zhí)行了xml方式的初始化 - > init-method"); } @PostConstruct public void doPostConstruct(){ System.out.println("執(zhí)行了注解的初始化 - > PostConstruct"); } /* 后置方法 :默認(rèn)情況不會(huì)顯式調(diào)用 */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("執(zhí)行了后置方法:postProcessAfterInitialization"); return bean; } //使用Bean public void sayHi(){ System.out.println("使用Bean -> sayHi()"); } /* 銷(xiāo)毀方法 */ @PreDestroy public void doPreDestroy(){ System.out.println("執(zhí)行了銷(xiāo)毀方法:PreDestroy"); } }
前置方法和后置方法: 默認(rèn)不會(huì)顯式調(diào)用
? 1.可以把作用域改為prototype
xml配置:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:content="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <bean id="beanLife" class="com.spring.demo.BeanLife" scope="prototype" init-method="myInit"></bean> </beans>
啟動(dòng)類(lèi):
public class App { public static void main(String[] args) { //此處使用ClassPathXmlApplicationContext,因?yàn)锳pplicationContext沒(méi)有銷(xiāo)毀方法 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.config.xml"); BeanLife beanLife = context.getBean("beanLife",BeanLife.class); //使用bean beanLife.sayHi(); //銷(xiāo)毀容器(bean也就銷(xiāo)毀了) context.destroy(); } }
執(zhí)行結(jié)果:
2.1、實(shí)例化和初始化的區(qū)別
實(shí)例化和屬性設(shè)置是java級(jí)別的系統(tǒng)“事件”,其操作過(guò)程不可人為干預(yù)和修改;而初始化是給開(kāi)發(fā)者提供的,可以在實(shí)例化之后,類(lèi)加載完成之前進(jìn)行自定義“事件”處理。
2.2、為什么先設(shè)置屬性再進(jìn)行初始化呢?
因?yàn)樵诔跏蓟A段可能會(huì)用到bean的屬性和方法;如果不先設(shè)置屬性,先初始化,那么在初始化階段使用屬性,就報(bào)錯(cuò)了;因?yàn)閷傩源藭r(shí)還沒(méi)裝配呢。
@Controller public class BController { @Autowired private User user1;//設(shè)置屬性 @PostConstruct//初始化 public void say(){ //再初始化中使用了user1里的屬性 System.out.println(user1.toString()); } } vate User user1;//設(shè)置屬性 @PostConstruct//初始化 public void say(){ //再初始化中使用了user1里的屬性 System.out.println(user1.toString()); } }
到此這篇關(guān)于Spring執(zhí)行流程和Bean的生命周期的文章就介紹到這了,更多相關(guān)Spring Bean生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Data JPA使用Sort進(jìn)行排序(Using Sort)
本篇文章主要介紹了Spring Data JPA使用Sort進(jìn)行排序(Using Sort),具有一定的參考價(jià)值,有興趣的可以了解一下2017-07-07java控制臺(tái)實(shí)現(xiàn)可視化日歷小程序
這篇文章主要為大家詳細(xì)介紹了java控制臺(tái)實(shí)現(xiàn)可視化日歷小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-12-12Java實(shí)現(xiàn)商品的查找、添加、出庫(kù)、入庫(kù)操作完整案例
這篇文章主要介紹了Java實(shí)現(xiàn)商品的查找、添加、出庫(kù)、入庫(kù)操作,結(jié)合完整實(shí)例形式分析了java基于面向?qū)ο蟮纳唐沸畔⑻砑?、刪除、查找等相關(guān)操作技巧,需要的朋友可以參考下2019-11-11jenkins和sonar實(shí)現(xiàn)代碼檢測(cè)過(guò)程詳解
這篇文章主要介紹了jenkins和sonar實(shí)現(xiàn)代碼檢測(cè)過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10springboot使用kafka推送數(shù)據(jù)到服務(wù)端的操作方法帶認(rèn)證
在使用Kafka進(jìn)行數(shù)據(jù)推送時(shí),遇到認(rèn)證問(wèn)題導(dǎo)致連接失敗,本文詳細(xì)介紹了Kafka的認(rèn)證配置過(guò)程,包括配置文件的引入和參數(shù)設(shè)置,實(shí)際測(cè)試表明,需要正確配置sasl.jaas.config以及其他認(rèn)證參數(shù),探討了配置文件是否可以同時(shí)存在多個(gè)配置塊的可能性,并提出了實(shí)際操作中的注意事項(xiàng)2024-11-11Spring AOP訪(fǎng)問(wèn)目標(biāo)方法的參數(shù)操作示例
這篇文章主要介紹了Spring AOP訪(fǎng)問(wèn)目標(biāo)方法的參數(shù)操作,結(jié)合實(shí)例形式詳細(xì)分析了spring面向切面AOP訪(fǎng)問(wèn)目標(biāo)方法的參數(shù)相關(guān)實(shí)現(xiàn)步驟與操作注意事項(xiàng),需要的朋友可以參考下2020-01-01如何使用兩個(gè)棧實(shí)現(xiàn)隊(duì)列Java
這篇文章主要介紹了如何使用兩個(gè)棧實(shí)現(xiàn)隊(duì)列Java,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11