亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring底層核心源碼原理解析

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

Spring核心知識(shí)點(diǎn)

本文章將對(duì)以下Spring核心知識(shí)進(jìn)行介紹。

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

2、依賴注入底層原理

3、初始化底層原理

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

5、AOP底層原理

6、Spring事務(wù)底層原理

這是入門時(shí)寫的Spring代碼

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

但是用ClassPathXmlApplicationContext其實(shí)已經(jīng)過時(shí)了,在新版的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)建一個(gè)對(duì)象?

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

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

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

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

3、Spring會(huì)根據(jù)某個(gè)規(guī)則生成當(dāng)前類對(duì)應(yīng)的beanName,作為key存入Map,當(dāng)前類作為value

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

Bean的創(chuàng)建過程

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

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

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

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

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

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

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

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

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

Bean對(duì)象創(chuàng)建出來(lái)后:

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

推斷構(gòu)造方法

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

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

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

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

AOP大致流程

AOP就是進(jìn)行動(dòng)態(tài)代理,在創(chuàng)建一個(gè)Bean的過程中,Spring在最后一步會(huì)去判斷當(dāng)前正在創(chuàng)建的這個(gè)Bean是不是需要進(jìn)行AOP,如果需要?jiǎng)t會(huì)進(jìn)行動(dòng)態(tài)代理。

如何判斷當(dāng)前Bean對(duì)象需不需要進(jìn)行AOP:

1、找出所有的切面Bean

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

3、如果寫了,則判斷所對(duì)應(yīng)的Pointcut是否和當(dāng)前Bean對(duì)象的類是否匹配

4、如果匹配則表示當(dāng)前Bean對(duì)象有匹配的的Pointcut,表示需要進(jìn)行AOP ?

Spring事務(wù)

當(dāng)在某個(gè)方法上加了@Transactional注解后,就表示該方法在調(diào)用時(shí)會(huì)開啟Spring事務(wù),而這個(gè)方法所在的類所對(duì)應(yīng)的Bean對(duì)象會(huì)是該類的代理對(duì)象。 ?

Spring事務(wù)的代理對(duì)象執(zhí)行某個(gè)方法時(shí)的步驟:

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

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

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

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

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

Spring事務(wù)是否會(huì)失效的判斷標(biāo)準(zhǔn):某個(gè)加了@Transactional注解的方法被調(diào)用時(shí),要判斷到底是不是直接被代理對(duì)象調(diào)用的,如果是則事務(wù)會(huì)生效,如果不是則失效。

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

相關(guān)文章

  • 一文搞懂Java SPI機(jī)制的原理與使用

    一文搞懂Java SPI機(jī)制的原理與使用

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

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

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

    Java利用Optional解決空指針異常

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

    Spring Boot事務(wù)配置操作

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

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

    這篇文章主要介紹了Java 3種方法實(shí)現(xiàn)進(jì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)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • java中Calendar.add()方法的使用

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

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

    springboot+dubbo+zookeeper的簡(jiǎn)單實(shí)例詳解

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

    JavaWeb項(xiàng)目部署到服務(wù)器詳細(xì)步驟詳解

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

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

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

最新評(píng)論