欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring底層核心源碼原理解析

 更新時間:2023年09月08日 09:55:48   作者:小滿和小晨  
這篇文章主要介紹了Spring底層核心源碼原理解析,當在某個方法上加了@Transactional注解后,就表示該方法在調(diào)用時會開啟Spring事務,而這個方法所在的類所對應的Bean對象會是該類的代理對象,需要的朋友可以參考下

Spring核心知識點

本文章將對以下Spring核心知識進行介紹。

1、Bean的生命周期底層原理

2、依賴注入底層原理

3、初始化底層原理

4、推斷構(gòu)造方法底層原理

5、AOP底層原理

6、Spring事務底層原理

這是入門時寫的Spring代碼

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();

但是用ClassPathXmlApplicationContext其實已經(jīng)過時了,在新版的Spring MVC和Spring Boot的底層主要用的都是AnnotationConfigApplicationContext,比如:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
//ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
UserService userService = (UserService) context.getBean("userService");
userService.test();

AppConfig.class和spring.xml一樣,表示Spring的配置,比如可以指定掃描路徑,可以直接定義Bean,比如:

spring.xml中的內(nèi)容為:

<context:component-scan base-package="com.zhouyu"/>
<bean id="userService" class="com.zhouyu.service.UserService"/>

AppConfig中的內(nèi)容為:

@ComponentScan("com.zhouyu")
public class AppConfig {
 @Bean
 public UserService userService(){
  return new UserService();
 }
}

Spring中是如何創(chuàng)建一個對象?

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();

在調(diào)用AnnotationConfigApplicationContext的構(gòu)造方法時,也就是第一行代碼,會去做一些事情:

1、解析AppConfig.class,得到掃描路徑

2、遍歷掃描路徑下的所有Java類,如果發(fā)現(xiàn)某個類上存在@Component、@Service等注解,那么Spring就把這個類記錄下來,存在一個Map中,比如Map<String, Class>。(實際上,Spring源碼中確實存在類似的這么一個Map,叫做BeanDefinitionMap)

3、Spring會根據(jù)某個規(guī)則生成當前類對應的beanName,作為key存入Map,當前類作為value

這樣,但調(diào)用context.getBean(“userService”)時,就可以根據(jù)"userService"找到UserService類,從而就可以去創(chuàng)建對象了。

Bean的創(chuàng)建過程

Bean創(chuàng)建的生命周期,大致過程如下

1、利用該類的構(gòu)造方法來實例化得到一個對象(但是如何一個類中有多個構(gòu)造方法,Spring則會進行選擇,這個叫做推斷構(gòu)造方法

2、得到一個對象后,Spring會判斷該對象中是否存在被@Autowired注解了的屬性,把這些屬性找出來并由Spring進行賦值(依賴注入

3、依賴注入后,Spring會判斷該對象是否實現(xiàn)了BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口,如果實現(xiàn)了,就表示當前對象必須實現(xiàn)該接口中所定義的setBeanName()、setBeanClassLoader()、setBeanFactory()方法,那Spring就會調(diào)用這些方法并傳入相應的參數(shù)(Aware回調(diào)

4、Aware回調(diào)后,Spring會判斷該對象中是否存在某個方法被@PostConstruct注解了,如果存在,Spring會調(diào)用當前對象的此方法(初始化前

5、緊接著,Spring會判斷該對象是否實現(xiàn)了InitializingBean接口,如果實現(xiàn)了,就表示當前對象必須實現(xiàn)該接口中的afterPropertiesSet()方法,那Spring就會調(diào)用當前對象中的afterPropertiesSet()方法(初始化

6、最后,Spring會判斷當前對象需不需要進行AOP,如果不需要那么Bean就創(chuàng)建完了,如果需要進行AOP,則會進行動態(tài)代理并生成一個代理對象做為Bean(初始化后

通過最后一步,可以發(fā)現(xiàn),當Spring根據(jù)UserService類來創(chuàng)建一個Bean時:

  • 如果不用進行AOP,那么Bean就是UserService類的構(gòu)造方法所得到的對象。
  • 如果需要進行AOP,那么Bean就是UserService的代理類所實例化得到的對象,而不是UserService本身所得到的對象。

Bean對象創(chuàng)建出來后:

  • 如果當前Bean是單例Bean,那么會把該Bean對象存入一個Map<String, Object>,Map的key為beanName,value為Bean對象。這樣下次getBean時就可以直接從Map中拿到對應的Bean對象了。(實際上,在Spring源碼中,這個Map就是單例池)
  • 如果當前Bean是原型Bean,那么后續(xù)沒有其他動作,不會存入一個Map,下次getBean時會再次執(zhí)行上述創(chuàng)建過程,得到一個新的Bean對象。

推斷構(gòu)造方法

如果一個類存在多個構(gòu)造方法,Spring會使用哪個呢?

1、如果一個類只存在一個構(gòu)造方法,不管該構(gòu)造方法是無參構(gòu)造方法,還是有參構(gòu)造方法,Spring都會用這個構(gòu)造方法

2、如果一個類存在多個構(gòu)造方法

  • 這些構(gòu)造方法中,存在一個無參的構(gòu)造方法,那么Spring就會用這個無參的構(gòu)造方法
  • 這些構(gòu)造方法中,不存在一個無參的構(gòu)造方法,那么Spring就會報錯
  • 如果某個構(gòu)造方法上加了@Autowired注解,那就表示程序員告訴Spring就用這個加了注解的方法,那Spring就會用這個加了@Autowired注解構(gòu)造方法了

AOP大致流程

AOP就是進行動態(tài)代理,在創(chuàng)建一個Bean的過程中,Spring在最后一步會去判斷當前正在創(chuàng)建的這個Bean是不是需要進行AOP,如果需要則會進行動態(tài)代理。

如何判斷當前Bean對象需不需要進行AOP:

1、找出所有的切面Bean

2、遍歷切面中的每個方法,看是否寫了@Before、@After等注解

3、如果寫了,則判斷所對應的Pointcut是否和當前Bean對象的類是否匹配

4、如果匹配則表示當前Bean對象有匹配的的Pointcut,表示需要進行AOP ?

Spring事務

當在某個方法上加了@Transactional注解后,就表示該方法在調(diào)用時會開啟Spring事務,而這個方法所在的類所對應的Bean對象會是該類的代理對象。 ?

Spring事務的代理對象執(zhí)行某個方法時的步驟:

1、判斷當前執(zhí)行的方法是否存在@Transactional注解

2、如果存在,則利用事務管理器(TransactionMananger)新建一個數(shù)據(jù)庫連接

3、修改數(shù)據(jù)庫連接的autocommit為false

4、執(zhí)行target.test(),執(zhí)行程序員所寫的業(yè)務邏輯代碼,也就是執(zhí)行sql

5、執(zhí)行完了之后如果沒有出現(xiàn)異常,則提交,否則回滾

Spring事務是否會失效的判斷標準:某個加了@Transactional注解的方法被調(diào)用時,要判斷到底是不是直接被代理對象調(diào)用的,如果是則事務會生效,如果不是則失效。

到此這篇關(guān)于Spring底層核心源碼原理解析的文章就介紹到這了,更多相關(guān)Spring核心原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文搞懂Java SPI機制的原理與使用

    一文搞懂Java SPI機制的原理與使用

    Java 程序員在日常工作中經(jīng)常會聽到 SPI,而且很多框架都使用了 SPI 的技術(shù),那么問題來了,到底什么是 SPI 呢?今天小編就帶大家好好了解一下 SPI
    2022-10-10
  • 解析JavaSe的內(nèi)部類

    解析JavaSe的內(nèi)部類

    這篇文章主要為大家詳細介紹了JavaSe的內(nèi)部類,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • Java利用Optional解決空指針異常

    Java利用Optional解決空指針異常

    這篇文章主要介紹了Java利用Optional解決空指針異常,Optional?類是一個包含有可選值的包裝類,這意味著?Optional?類既可以含有對象也可以為空
    2022-09-09
  • Spring Boot事務配置操作

    Spring Boot事務配置操作

    這篇文章主要介紹了Spring Boot事務配置操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java 3種方法實現(xiàn)進制轉(zhuǎn)換

    Java 3種方法實現(xiàn)進制轉(zhuǎn)換

    這篇文章主要介紹了Java 3種方法實現(xiàn)進制轉(zhuǎn)換,幫助大家利用Java處理數(shù)據(jù),感興趣的朋友可以了解下
    2020-09-09
  • Java中final關(guān)鍵字的使用與注意總結(jié)

    Java中final關(guān)鍵字的使用與注意總結(jié)

    這篇文章主要給大家介紹了關(guān)于Java中final關(guān)鍵字的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2020-08-08
  • java中Calendar.add()方法的使用

    java中Calendar.add()方法的使用

    本文主要介紹了java中Calendar.add()方法的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • springboot+dubbo+zookeeper的簡單實例詳解

    springboot+dubbo+zookeeper的簡單實例詳解

    本文主要介紹了springboot+dubbo+zookeeper的簡單實例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • JavaWeb項目部署到服務器詳細步驟詳解

    JavaWeb項目部署到服務器詳細步驟詳解

    這篇文章主要介紹了JavaWeb項目如何部署到服務器,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-04-04
  • Gateway如何實現(xiàn)全局跨域

    Gateway如何實現(xiàn)全局跨域

    這篇文章主要介紹了Gateway如何實現(xiàn)全局跨域問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04

最新評論