国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring源碼系列:核心概念解析

這篇具有很好參考價值的文章主要介紹了Spring源碼系列:核心概念解析。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

前言

本文旨在為讀者解析Spring源碼中的關(guān)鍵類,以便讀者在深入閱讀源碼時,能夠了解關(guān)鍵類的作用和用途。在閱讀Spring源碼時,經(jīng)常會遇到一些不熟悉的概念,了解關(guān)鍵類的作用可以幫助讀者更好地理解這些概念。

BeanDefinition

BeanDefinition是Spring框架中的一個重要概念,它定義了一個Bean的基本屬性和行為,比如:

  1. BeanClassName,當(dāng)前的bean名字
  2. Scope,是否單例,具體枚舉:#SCOPE_SINGLETON、#SCOPE_PROTOTYPE
  3. LazyInit,是否懶加載,默認(rèn)不是
  4. DependsOn,是否依賴其他bean,如果依賴,則會先創(chuàng)建依賴bean
  5. InitMethodName,初始化方法名稱
  6. DestroyMethodName,銷毀類方法名稱
  7. ......還有更多,但是這幾個大體已經(jīng)差不多了

BeanDefinition的作用非常重要,它可以幫助Spring容器更好地管理Bean的生命周期和依賴關(guān)系。在Spring框架中,我們經(jīng)常會通過注解方式來定義Bean:

  1. < bean/>
  2. @Bean
  3. @Component(@Controller、@Service)

這些都是被稱為申明式定義Bean。就是使用Spring提供好的封裝。

除了注解方式,我們還可以通過編程方式來定義Bean,這時就需要直接使用BeanDefinition來創(chuàng)建BeanDefinition對象,并設(shè)置對應(yīng)的屬性,然后將其注冊到Spring容器中,比如

    // 創(chuàng)建一個Spring容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
        beanDefinition.setBeanClass(UserService.class);
        //當(dāng)然還可以設(shè)置其他上面我說的其他屬性:懶加載什么的
        applicationContext.registerBeanDefinition("userService", beanDefinition);

        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.test();

無論是通過注解方式還是編程方式來定義Bean,最終都是需要使用BeanDefinition來描述Bean的基本屬性和行為,然后將其放入Spring容器中進(jìn)行管理。

BeanDefinitionReader

BeanDefinitionReader是Spring框架中的一個重要組件,主要用于讀取和操作BeanDefinition對象。雖然我們在使用Spring框架時很少直接使用BeanDefinitionReader,但在Spring源碼中卻扮演著非常重要的角色,相當(dāng)于Spring源碼的基礎(chǔ)設(shè)施。

BeanDefinitionReader的核心方法包括以下幾個:

  1. BeanDefinitionRegistry,用來注冊bean定義,相當(dāng)于一個工廠
  2. BeanNameGenerator,用來生成bean名字的生成器
  3. loadBeanDefinitions,從資源中加載bean

XmlBeanDefinitionReader

XmlBeanDefinitionReader是BeanDefinitionReader的子類,可以用于從XML文件中讀取BeanDefinition并注冊到Spring容器中。使用XmlBeanDefinitionReader的步驟如下:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
//加載xml中配置的所有<bean>
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");
System.out.println(context.getBean("userService"))

AnnotatedBeanDefinitionReader

細(xì)心的朋友,應(yīng)該可以發(fā)現(xiàn)AnnotatedBeanDefinitionReader是一個單獨(dú)的類,不是BeanDefinitionReader的子類,但它的方法與BeanDefinitionReader基本相同,官方說是方便的適配器,用于編程注冊bean類,他可以解析@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description相關(guān)注解,具體操作如下:

// 創(chuàng)建一個Spring容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

//        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
//        beanDefinition.setBeanClass(UserService.class);
//        applicationContext.registerBeanDefinition("userService", beanDefinition);

        new AnnotatedBeanDefinitionReader(applicationContext).registerBean(UserService.class);

        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.test();

同樣的,他也可以讓我們注冊的bean走完創(chuàng)建的整個生命周期過程。

ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner也是一個用于注冊BeanDefinition的工具類,與BeanDefinition接口沒有直接關(guān)系。ClassPathBeanDefinitionScanner可以掃描指定包路徑下帶有特定注解的類,并將其解析成BeanDefinition,注冊到Spring容器中。主要是他有個scan方法對我們定義的basepackage包路徑進(jìn)行解析掃描所有帶有@component、@ManagedBean(JSR-250標(biāo)準(zhǔn))、@Named(JSR-330標(biāo)準(zhǔn))
使用ClassPathBeanDefinitionScanner的步驟如下:

// 創(chuàng)建一個Spring容器  
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);  
  
new ClassPathBeanDefinitionScanner(applicationContext).scan("com.xiaoyu");  
UserService userService = (UserService) applicationContext.getBean("userService");  
userService.test();

BeanFactory

BeanFactory是Spring框架中的一個重要接口,他就是Spring用于管理Bean對象的創(chuàng)建和管理,看他的幾個主要方法就知道了:

  1. getBean,可以根據(jù)name、type等獲取bean對象
  2. containsBean,是否bean工廠中有某個對象
  3. isSingleton,判斷是否是單例
  4. isTypeMatch,判斷改name是否匹配類型
  5. getType,根據(jù)bean名字獲取類型
  6. getAliases。獲取別名數(shù)組
    看著主要幾個接口實(shí)現(xiàn),基本都是圍繞bean所做的,然后根據(jù)接口再看他的實(shí)現(xiàn)類就方便許多了,

DefaultListableBeanFactory

如果看過源碼的朋友肯定對這個實(shí)現(xiàn)類不陌生,如果對這個實(shí)現(xiàn)類陌生的朋友,那請記住這個重要的實(shí)現(xiàn)類,它實(shí)現(xiàn)了很多接口、且繼承了多層父類,所以他的功能也是相當(dāng)之多。我們來看看他的主要方法:

  1. containsBeanDefinition,查看是否包含某個bean定義,因為該類維護(hù)了一個Map<String, BeanDefinition> beanDefinitionMap屬性。
  2. determineAutowireCandidate,決定注入哪個bean,@Primary-->優(yōu)先級最高--->name
  3. doResolveDependency,解析依賴,進(jìn)行注入
  4. registerBeanDefinition,注冊bean定義到beanDefinitionMap屬性
  5. preInstantiateSingletons,進(jìn)行創(chuàng)建bean實(shí)例

具體使用操作也是基本類似的

AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();  
beanDefinition.setBeanClass(UserService.class);  
defaultListableBeanFactory.registerBeanDefinition("userService",beanDefinition);  
  
UserService userService1 = (UserService) defaultListableBeanFactory.getBean("userService");  
userService1.test();

從他的結(jié)構(gòu)圖也能看出來:

Spring源碼系列:核心概念解析

AbstractBeanFactory

該類是抽象bean,介紹他主要目的就是getbean時,走的主要邏輯就是該類實(shí)現(xiàn)的dogetbean方法(請記住這個重要的方法),所以確實(shí)需要關(guān)注下,主要方法如下:

  1. doGetBean,獲取bean的主要邏輯,沒有則創(chuàng)建
  2. getMergedBeanDefinition,bean定義的合并邏輯,主要是將父類beanfactory中的屬性被子類覆蓋

AbstractAutowireCapableBeanFactory

繼承自剛才提到的AbstractBeanFactory,主要方法如下:

  1. autowireByName,按照name注入
  2. autowireByType,根據(jù)類型
  3. createBean,創(chuàng)建bean流程,實(shí)例化前可以使用BeanPostProcessors后置處理器
  4. createBeanInstance,正在創(chuàng)建bean,這邊使用到了之前入門講過的推斷構(gòu)造器實(shí)現(xiàn)實(shí)例化
  5. doCreateBean,創(chuàng)建bean,循環(huán)依賴、屬性填充、初始化
  6. initializeBean,初始化bean,包括初始化前、初始化、初始化后
  7. instantiateUsingFactoryMethod,利用factorymethod初始化bean
  8. invokeAwareMethods,初始化bean時的回調(diào)函數(shù)Aware接口
  9. populateBean,初始化之前,屬性賦值

可以從他的關(guān)鍵方法看出,主要作用就是初始化bean的全過程,也是很重要的類

HierarchicalBeanFactory

這里說下HierarchicalBeanFactory類,他只是一個接口類,但是如果想要使用beanfactory的層次結(jié)構(gòu),例如獲取父beanfactory,那就必須實(shí)現(xiàn)HierarchicalBeanFactory類,比如前面說的bean定義的合并邏輯,就需要獲取父beanfactory,從而實(shí)現(xiàn)父子bean定義的覆蓋合并

ApplicationContext

ApplicationContext是個接口,實(shí)際上也是一個BeanFactory,不過比BeanFactory
更加強(qiáng)大,它本身并沒有太多方法,但是它繼承了很多接口,因為接口之間是可以多繼承的。

Spring源碼系列:核心概念解析

關(guān)于他的父接口,這里不做多說明,詳情的話請看下子文章(后續(xù)更新)。

AnnotationConfigApplicationContext

一看這個類,大家都知道了,我們用的實(shí)例全是用這個類去啟動我們的spring的,我們看看他的主要方法:

  1. AnnotationConfigApplicationContext,構(gòu)造器,會初始化DefaultListableBeanFactory、AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner;然后開始調(diào)用refresh()方法。
  2. register,會使用編程式定義將bean注入spring容器。就如我們的APPConfig
  3. scan,走ClassPathBeanDefinitionScanner的scan,掃描包路徑,將聲明式的bean注入進(jìn)spring容器
  4. setBeanNameGenerator,bean名稱生成器

ClassPathXmlApplicationContext

主要就是去解析xml配置的bean定義將其注入到spring容器中,功能其實(shí)跟AnnotationConfigApplicationContext類似,但是卻沒有AnnotationConfigApplicationContext強(qiáng)大,比如不能注冊BeanDefinition。

BeanPostProcessor

BeanPostProcess表示Bena的后置處理器,可以有多個BeanPostProcessor,我們自己也可以去定義一個BeanPostProcessor;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        if ("userService".equals(beanName)) {
            System.out.println("userService");
            return new User();
        }
        System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        System.out.println("MyBeanPostProcessor.postProcessAfterInitialization");
        return bean;
    }

我們可以通過實(shí)現(xiàn)bean的后置處理器,來對某一個bean或者所有bean的進(jìn)行干預(yù),博主只是隨便寫了一個,沒有什么太大意義。

BeanFactoryPostProcessor

BeanFactoryPostProcessor表示Bean工廠的后置處理器,其實(shí)和BeanPostProcessor類似,BeanPostProcessor是干涉Bean的創(chuàng)建過程,BeanFactoryPostProcessor是干涉BeanFactory的創(chuàng)建過程,我們也可以自定義:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("加工beanFactory");
    }
}

FactoryBean

FactoryBean和BeanFactory不是一個東西,大家不要混淆兩個概念,BeanFactory是管理我們注入的bean等,而FactoryBean本身也會被Spring管理,一旦Spring知道我們的bean實(shí)現(xiàn)了FactoryBean,那么會自動調(diào)用getObject方法獲取我們自己創(chuàng)建的bean,這個bean完完全全交給我們自己創(chuàng)建了,我們可以這樣定義一個FactoryBean:


@Component
public class MyFactoryBean implements FactoryBean {

    @Override
    public Object getObject() throws Exception {
        UserService service = new UserService();
        return service;
    }

    @Override
    public Class<?> getObjectType() {
        return UserService.class;
    }

}

但是需要注意的是,這些注入UserService時,是不會有屬性依賴注入的,畢竟他沒有走bean的生命創(chuàng)建周期。細(xì)心的朋友會發(fā)現(xiàn),這根我在配置類中寫@bean形式的類有啥區(qū)別,現(xiàn)象來講,他倆都可以被創(chuàng)建出來,但是值得一提的是,F(xiàn)actoryBean創(chuàng)建出來的bean是沒走spring定義的bean生命周期的。

MetadataReader、ClassMetadata、AnnotationMetadata

Spring啟動時需要掃描指定包路徑下的所有類文件來獲取需要注入或管理的Bean信息。然而,并非所有類都是需要的,這時可以使用ASM技術(shù)來解析類文件的元數(shù)據(jù)信息,包括類上的注解信息和類的基本信息。ASM技術(shù)可以在運(yùn)行時動態(tài)生成和修改Java字節(jié)碼,從而高效地解析類文件的元數(shù)據(jù)信息,避免了大量的IO操作和類加載,提高了應(yīng)用的性能。以下是一個簡單的實(shí)例:

        SimpleMetadataReaderFactory simpleMetadataReaderFactory = new SimpleMetadataReaderFactory();
        MetadataReader metadataReader = simpleMetadataReaderFactory.getMetadataReader("com.xiaoyu.service.UserService");
        System.out.println(metadataReader.getClassMetadata().getClassName());
        metadataReader.getAnnotationMetadata().getAnnotationTypes().forEach(System.out::println);

結(jié)語

通過本文的解析,我們大致了解了Spring框架中的一些關(guān)鍵組件及其用途,這有助于我們在深入理解Spring源碼過程中建立起一個整體框架。Spring源碼量很大,要真正理解透徹還需要投入大量時間進(jìn)行細(xì)致學(xué)習(xí)和總結(jié)。但如果先對一些關(guān)鍵組件有一個大致的認(rèn)識,有助于我們進(jìn)行針對性學(xué)習(xí),避免迷失在繁雜的細(xì)節(jié)中。希望本文能夠?qū)ψx者有一定的幫助,更希望讀者在學(xué)習(xí)Spring源碼的過程中,不斷總結(jié)和提高,并在一定階段有所突破。祝讀者順利文章來源地址http://www.zghlxwxcb.cn/news/detail-419498.html

到了這里,關(guān)于Spring源碼系列:核心概念解析的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Spring Security系列】一文帶你了解權(quán)限框架與Spring Security核心概念

    【Spring Security系列】一文帶你了解權(quán)限框架與Spring Security核心概念

    權(quán)限框架是軟件開發(fā)中用于管理 用戶權(quán)限和訪問控制 的工具。在企業(yè)或者我們畢設(shè)復(fù)雜的系統(tǒng)中,不同的用戶或角色需要擁有不同的訪問和操作權(quán)限,以確保系統(tǒng)的安全性和數(shù)據(jù)完整性。今天我們就討論一下Java中的安全框架! 在企業(yè)的開發(fā)中,Spring Security,Shiro都是比較流

    2024年04月16日
    瀏覽(18)
  • 本文將從云原生的概念、背景知識、Kubernetes架構(gòu)及核心組件、應(yīng)用場景、案例研究等方面深入剖析云原生課程的相關(guān)知識點(diǎn)

    作者:禪與計算機(jī)程序設(shè)計藝術(shù) 2020年,技術(shù)快速發(fā)展,云計算火爆。云原生領(lǐng)域也隨之蓬勃發(fā)展。云原生已經(jīng)成為大勢所趨,大量企業(yè)都在逐漸轉(zhuǎn)型云原生應(yīng)用架構(gòu)。國內(nèi)外云服務(wù)廠商也紛紛推出基于Kubernetes的服務(wù)平臺,而Kubernetes又是云原生開源技術(shù)體系的一部分。為了幫

    2024年02月07日
    瀏覽(50)
  • 從零開始學(xué)Spring Boot系列-前言

    在數(shù)字化和信息化的時代,Java作為一種成熟、穩(wěn)定且廣泛應(yīng)用的編程語言,已經(jīng)成為構(gòu)建企業(yè)級應(yīng)用的首選。而在Java生態(tài)系統(tǒng)中,Spring框架無疑是其中最為耀眼的一顆明星。它提供了全面的編程和配置模型,用于構(gòu)建企業(yè)級應(yīng)用。隨著Spring Boot的出現(xiàn),這一框架變得更加易于

    2024年02月22日
    瀏覽(35)
  • Spring-底層架構(gòu)核心概念

    BeanDefinition BeanDefinition表示Bean定義,有很多屬性用來描述Bean的特點(diǎn): class,表示Bean類型 scope,表示Bean作用域,單例或原型等 lazyInit:表示Bean是否是懶加載 initMethodName:表示Bean初始化時要執(zhí)行的方法 destroyMethodName:表示Bean銷毀時要執(zhí)行的方法 還有很多... 定義Bean的方式主要

    2024年02月08日
    瀏覽(24)
  • Spring底層架構(gòu)核心概念

    Spring底層架構(gòu)核心概念

    BeanDefinition表示Bean定義,BeanDefinition中存在很多屬性用來描述一個Bean的特點(diǎn)。比如: class,表示Bean類型 scope,表示Bean作用域,單例或原型等 lazyInit:表示Bean是否是懶加載 initMethodName:表示Bean初始化時要執(zhí)行的方法 destroyMethodName:表示Bean銷毀時要執(zhí)行的方法 還有很多… 在

    2024年02月07日
    瀏覽(25)
  • 一起學(xué)Elasticsearch系列-核心概念

    本文已收錄至Github,推薦閱讀 ?? Java隨想錄 微信公眾號:Java隨想錄 開個新的坑,創(chuàng)作關(guān)于Elasticsearch的系列文章 首先,讓我們簡單的了解一下Elasticsearch: Elasticsearch是一個開源的搜索和分析引擎,支持近實(shí)時的大數(shù)據(jù)存儲、搜索和分析。它基于Apache Lucene項目,提供全文搜索

    2024年02月01日
    瀏覽(51)
  • Spring 核心概念之一 IoC

    歡迎來到本篇文章!通過上一篇什么是 Spring?為什么學(xué)它?的學(xué)習(xí),我們知道了 Spring 的基本概念,知道什么是 Spring,以及為什么學(xué)習(xí) Spring。 今天,這篇就來說說 Spring 中的核心概念之一 IoC。 IoC 這個概念對于初學(xué)者來說還真不是很好理解,我就是那個理解不了的初學(xué)者。

    2024年02月07日
    瀏覽(19)
  • Spring概述與核心概念學(xué)習(xí) -- Spring入門(一)

    Spring概述與核心概念學(xué)習(xí) -- Spring入門(一)

    為了鞏固所學(xué)的知識,作者嘗試著開始發(fā)布一些學(xué)習(xí)筆記類的博客,方便日后回顧。當(dāng)然,如果能幫到一些萌新進(jìn)行新技術(shù)的學(xué)習(xí)那也是極好的。作者菜菜一枚,文章中如果有記錄錯誤,歡迎讀者朋友們批評指正。 (博客的參考源碼以及可以在我主頁的資源里找到,如果在學(xué)

    2024年02月16日
    瀏覽(98)
  • 三分鐘白話RocketMQ系列—— 核心概念

    三分鐘白話RocketMQ系列—— 核心概念

    目錄 摘要 Q1:RocketMQ是什么? Q2: 作為消息中間件,RocketMQ和kafka有什么區(qū)別? Q3: RocketMQ的基本架構(gòu)是怎樣的? Q4:RocketMQ有哪些核心概念? 總結(jié) RocketMQ是一個開源的分布式消息中間件。它是一種低延遲、高可用、高可靠、高并發(fā)的消息隊列系統(tǒng),用于在分布式系統(tǒng)中進(jìn)

    2024年02月14日
    瀏覽(22)
  • Python與Pytorch系列(二) 本文(1.8萬字) | 解析Opencv, Matplotlib, PIL | 三者之間的轉(zhuǎn)換 | 三者對JPG和PNG讀取和寫入 |

    點(diǎn)擊進(jìn)入專欄: 《人工智能專欄》 Python與Python | 機(jī)器學(xué)習(xí) | 深度學(xué)習(xí) | 目標(biāo)檢測 | YOLOv5及其改進(jìn) | YOLOv8及其改進(jìn) | 關(guān)鍵知識點(diǎn) | 各種工具教程 推薦網(wǎng)站 : OpenCV Matplotlib Pillow opencv的基本圖像類型可以和numpy數(shù)組相互轉(zhuǎn)化,因此可以直接調(diào)用 torch.from_numpy(img) 將圖像轉(zhuǎn)換成 t

    2024年02月03日
    瀏覽(108)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包