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

Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理解析

 更新時(shí)間:2022年09月30日 09:41:19   作者:融極  
這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

概述

我們現(xiàn)在來(lái)學(xué)習(xí)一下Spring里面的一些擴(kuò)展原理,希望大家通過(guò)這些原理的學(xué)習(xí),對(duì)Spring里面的運(yùn)行機(jī)制,包括其內(nèi)部的工作原理,能有一個(gè)非常深刻的認(rèn)識(shí),為以后學(xué)習(xí)Spring里面的其他框架會(huì)有較大的幫助。

BeanFactoryPostProcessor的調(diào)用時(shí)機(jī)

BeanFactoryPostProcessor其實(shí)就是BeanFactory(創(chuàng)建bean的工廠)的后置處理器。

看到BeanFactoryPostProcessor會(huì)聯(lián)想到BeanPostProcessor,之前說(shuō)過(guò)它是bean的后置處理器,并且是在bean創(chuàng)建對(duì)象初始化前后進(jìn)行攔截工作的。

看完接口上的描述后,我們可以指定BeanFactoryPostProcessor的調(diào)用時(shí)機(jī)。意思是在IOC容器的BeanFactory標(biāo)準(zhǔn)初始化完成之后,修改IOC容器里面的BeanFactory。

什么是標(biāo)準(zhǔn)初始化么?后面描述是所有的bean定義已經(jīng)被加載了,但是還沒(méi)有bean被初始化。

總結(jié):BeanFactoryPostProcessor的調(diào)用時(shí)機(jī)是在BeanFactory標(biāo)準(zhǔn)化之后,我們可以定制、修改BeanFactory里面的一些內(nèi)容,此時(shí),所有的bean定義已經(jīng)被加載到BeanFactory中了,但是bean的實(shí)例還沒(méi)創(chuàng)建。

案例實(shí)踐

首先編寫(xiě)一個(gè)類(lèi)實(shí)現(xiàn)BeanFactoryPostProcessor接口。

package com.meimeixia.ext;
import java.util.Arrays;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
		System.out.println("MyBeanFactoryPostProcessor...postProcessBeanFactory..."); // 這個(gè)時(shí)候我們所有的bean還沒(méi)被創(chuàng)建
		                                                                              // 但是我們可以看一下通過(guò)Spring給我們傳過(guò)來(lái)的這個(gè)beanFactory,我們能拿到什么
		int count = beanFactory.getBeanDefinitionCount(); // 我們能拿到有幾個(gè)bean定義
		String[] names = beanFactory.getBeanDefinitionNames(); // 除此之外,我們還能拿到每一個(gè)bean定義的名字
		System.out.println("當(dāng)前BeanFactory中有" + count + "個(gè)Bean");
		System.out.println(Arrays.asList(names));
	}
}

注意,我們自己編寫(xiě)的MyBeanFactoryPostProcessor類(lèi)要想讓Spring知道,并且還要能被使用起來(lái),那么它一定就得被加到容器中,為此,我們可以在其上標(biāo)注一個(gè)@Component注解。

然后創(chuàng)建一個(gè)配置類(lèi),例如ExtConfig,在該配置類(lèi)上使用@ComponentScan注解來(lái)配置包掃描。

package com.meimeixia.ext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.meimeixia.bean.Blue;

@ComponentScan("com.meimeixia.ext")
@Configuration
public class ExtConfig {
	@Bean
	public Blue blue() {
		return new Blue();
	}	
}

package com.meimeixia.bean;

public class Blue {

	public Blue() {
		System.out.println("blue...constructor");
	}
	
	public void init() {
		System.out.println("blue...init...");
	}
	
	public void destory() {
		System.out.println("blue...destory...");
	}
}

編寫(xiě)測(cè)試類(lèi)

package com.meimeixia.test;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.meimeixia.ext.ExtConfig;

public class IOCTest_Ext {
	
	@Test
	public void test01() {
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
		// 關(guān)閉容器
		applicationContext.close();
	}
}

接下來(lái)測(cè)試下BeanFactoryPostProcessor的調(diào)用時(shí)機(jī)。

我們看到自己編寫(xiě)的BeanFactoryPostProcessor在Blue類(lèi)的無(wú)參構(gòu)造器創(chuàng)建Blue對(duì)象之前就已經(jīng)工作了。我們看看到Blue組件注冊(cè)到容器中的名字,只是此刻還沒(méi)有創(chuàng)建對(duì)象。

說(shuō)明BeanFactoryPostProcessor是在所有的bean定義信息都被加載之后才調(diào)用的。

源碼分析

鼠標(biāo)單擊Eclipse左上角方法調(diào)用棧中的IOCTest_Ext.test01() line:12,這時(shí)程序來(lái)到了IOCTest_Ext類(lèi)的test01方法中,如下圖所示。

繼續(xù)跟進(jìn)代碼,可以看到創(chuàng)建IOC容器時(shí),最后還得刷新容器,如下圖所示。

繼續(xù)跟進(jìn)代碼,可以看到在刷新容器的過(guò)程中,還得執(zhí)行在容器中注冊(cè)的BeanFactoryPostProcessor(BeanFactory的后置處理器)的方法。

那具體是怎么來(lái)執(zhí)行BeanFactoryPostProcessor的呢?我們繼續(xù)跟進(jìn)代碼,發(fā)現(xiàn)又調(diào)用了一個(gè)invokeBeanFactoryPostProcessors方法,如下圖所示。

下面我們來(lái)仔細(xì)分析一下PostProcessorRegistrationDelegate類(lèi)中的invokeBeanFactoryPostProcessors方法具體都做了哪些操作。

會(huì)發(fā)現(xiàn)其遍歷了所有的BeanFactoryPostProcessor組件,我們自己編寫(xiě)的實(shí)現(xiàn)了BeanFactoryPostProcessor接口的MyBeanFactoryPostProcessor類(lèi)肯定也屬于其中,所以會(huì)被遍歷到,然后便會(huì)執(zhí)行其postProcessBeanFactory方法。

小結(jié)

經(jīng)過(guò)源碼分析,我們可以得出這樣一個(gè)結(jié)論:首先從IOC容器中找到所有類(lèi)型是BeanFactoryPostProcessor的組件,然后再來(lái)執(zhí)行它們其中的方法,而且是在初始化創(chuàng)建其他組件前面執(zhí)行。

為什么在初始化其他組件前面執(zhí)行的呢,之前我們分析AOP原理是,bean的初始化是放在finishBeanFactoryInitialization(beanFactory)方法執(zhí)行的。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的悲觀鎖與樂(lè)觀鎖是什么

    Java中的悲觀鎖與樂(lè)觀鎖是什么

    這篇文章主要介紹了Java中的悲觀鎖與樂(lè)觀鎖是什么,幫助大家更好的理解和學(xué)習(xí)Java鎖的相關(guān)知識(shí),感興趣的朋友可以了解下
    2020-09-09
  • Java中的System.arraycopy()淺復(fù)制方法詳解

    Java中的System.arraycopy()淺復(fù)制方法詳解

    這篇文章主要介紹了Java中的System.arraycopy()淺復(fù)制方法詳解,Java數(shù)組的復(fù)制操作可以分為深度復(fù)制和淺度復(fù)制,簡(jiǎn)單來(lái)說(shuō)深度復(fù)制,可以將對(duì)象的值和對(duì)象的內(nèi)容復(fù)制;淺復(fù)制是指對(duì)對(duì)象引用的復(fù)制,需要的朋友可以參考下
    2023-11-11
  • MyBatis與MyBatis-Plus的區(qū)別詳解

    MyBatis與MyBatis-Plus的區(qū)別詳解

    本文主要介紹了MyBatis與MyBatis-Plus的區(qū)別詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • 關(guān)于BufferedReader的read()和readLine()的區(qū)別

    關(guān)于BufferedReader的read()和readLine()的區(qū)別

    這篇文章主要介紹了關(guān)于BufferedReader的read()和readLine()的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Mybatis自定義TypeHandler解決特殊類(lèi)型轉(zhuǎn)換問(wèn)題詳解

    Mybatis自定義TypeHandler解決特殊類(lèi)型轉(zhuǎn)換問(wèn)題詳解

    這篇文章主要介紹了Mybatis自定義TypeHandler解決特殊類(lèi)型轉(zhuǎn)換問(wèn)題詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • SpringCloud feign無(wú)法注入接口的問(wèn)題

    SpringCloud feign無(wú)法注入接口的問(wèn)題

    這篇文章主要介紹了SpringCloud feign無(wú)法注入接口的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • Java異常處理try?catch的基本用法

    Java異常處理try?catch的基本用法

    try就像一個(gè)網(wǎng),把try{}里面的代碼所拋出的異常都網(wǎng)住,然后把異常交給catch{}里面的代碼去處理。最后執(zhí)行finally之中的代碼。無(wú)論try中代碼有沒(méi)有異常,也無(wú)論catch是否將異常捕獲到,finally中的代碼都一定會(huì)被執(zhí)行。
    2021-12-12
  • Intellij無(wú)法創(chuàng)建java文件解決方案

    Intellij無(wú)法創(chuàng)建java文件解決方案

    這篇文章主要介紹了Intellij無(wú)法創(chuàng)建java文件解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Spring?Boot中application配置文件的生效順序及應(yīng)用范圍

    Spring?Boot中application配置文件的生效順序及應(yīng)用范圍

    Spring?Boot的一個(gè)重要特性就是它的自動(dòng)配置,這一特性在很大程度上依賴(lài)于名稱(chēng)為application的配置文件,本文將詳細(xì)介紹在Spring?Boot中,這些配置文件的加載順序以及每份文件的應(yīng)用范圍,需要的朋友可以參考下
    2024-03-03
  • Maven基礎(chǔ)知識(shí)大梳理

    Maven基礎(chǔ)知識(shí)大梳理

    這篇文章主要是Maven基礎(chǔ)知識(shí)大梳理,Maven主要是用來(lái)解決導(dǎo)入java類(lèi)依賴(lài)的jar,編譯java項(xiàng)目主要問(wèn)題,大家可以讀一讀這篇文章,更深一步的了解Maven
    2021-08-08

最新評(píng)論