Spring類

BeanDefinition

BeanDefinition表示Bean定義,BeanDefinition中存在很多屬性用來描述一個Bean的特點。比如:

  • class,表示Bean類型
  • scope,表示Bean作用域,單例或原型等
  • lazyInit:表示Bean是否是懶加載
  • initMethodName:表示Bean初始化時要執行的方法
  • destroyMethodName:表示Bean銷毀時要執行的方法
  • 還有很多…

BeanDefinitionReader

接下來,我們來介紹幾種在Spring源碼中所提供的BeanDefinition讀取器(BeanDefinitionReader),這些BeanDefinitionReader在我們使用Spring時用得少,但在Spring源碼中用得多,相當于Spring源碼的基礎設施。

AnnotatedBeanDefinitionReader

可以直接把某個類轉換為BeanDefinition,并且會解析該類上的注解,比如

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(context);// 將User.class解析為BeanDefinition
annotatedBeanDefinitionReader.register(User.class);System.out.println(context.getBean("user"));

注意:它能解析的注解是:@Conditional,@Scope、@Lazy、@Primary、@DependsOn、@Role、@Description

XmlBeanDefinitionReader

可以解析標簽

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(context);
int i = xmlBeanDefinitionReader.loadBeanDefinitions("spring.xml");System.out.println(context.getBean("user"));

ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner是掃描器,但是它的作用和BeanDefinitionReader類似,它可以進行掃描,掃描某個包路徑,對掃描到的類進行解析,比如,掃描到的類上如果存在@Component注解,那么就會把這個類解析為一個BeanDefinition,比如:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.refresh();ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan("com.zhouyu");System.out.println(context.getBean("userService"));

BeanFactory

BeanFactory表示**Bean工廠**,所以很明顯,BeanFactory會負責創建Bean,并且提供獲取Bean的API。

而ApplicationContext是BeanFactory的一種,在Spring源碼中,是這么定義的:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
}

ApplicationContext

上面有分析到,ApplicationContext是個接口,實際上也是一個BeanFactory,不過比BeanFactory更加強大,比如:

  1. HierarchicalBeanFactory:擁有獲取父BeanFactory的功能
  2. ListableBeanFactory:擁有獲取beanNames的功能
  3. ResourcePatternResolver:資源加載器,可以一次性獲取多個資源(文件資源等等)
  4. EnvironmentCapable:可以獲取運行時環境(沒有設置運行時環境功能)
  5. ApplicationEventPublisher:擁有廣播事件的功能(沒有添加事件監聽器的功能)
  6. MessageSource:擁有國際化功能

AnnotationConfigApplicationContext

  1. ConfigurableApplicationContext:繼承了ApplicationContext接口,添加事件監聽器、添加BeanFactoryPostProcessor、設置Environment,獲取ConfigurableListableBeanFactory等功能
  2. AbstractApplicationContext:實現了ConfigurableApplicationContext接口
  3. GenericApplicationContext:繼承了AbstractApplicationContext,實現了BeanDefinitionRegistry接口,擁有了所有ApplicationContext的功能,并且可以注冊BeanDefinition,注意這個類中有一個屬性(DefaultListableBeanFactory beanFactory)
  4. AnnotationConfigRegistry:可以單獨注冊某個類為BeanDefinition(可以處理該類上的@Configuration注解,已經可以處理@Bean注解),同時可以掃描。
  5. AnnotationConfigApplicationContext:繼承了GenericApplicationContext,實現了AnnotationConfigRegistry接口,擁有了以上所有的功能

ClassPathXmlApplicationContext

它也是繼承了AbstractApplicationContext,但是相對于AnnotationConfigApplicationContext而言,功能沒有AnnotationConfigApplicationContext強大,比如不能注冊BeanDefinition。

OrderComparator

OrderComparator是Spring所提供的一種比較器,可以用來根據@Order注解或實現Ordered接口來執行值進行筆記,從而可以進行排序。

BeanPostProcessor

BeanPostProcess表示Bena的后置處理器,我們可以定義一個或多個BeanPostProcessor,比如通過一下代碼定義一個BeanPostProcessor:

@Component
public class ZhouyuBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {if ("userService".equals(beanName)) {System.out.println("初始化前");}return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {if ("userService".equals(beanName)) {System.out.println("初始化后");}return bean;}
}

**一個BeanPostProcessor可以在任意一個Bean的初始化之前以及初始化之后去額外的做一些用戶自定義的邏輯,當然,我們可以通過判斷beanName來進行針對性處理(針對某個Bean,或某部分Bean)。**可以通過定義BeanPostProcessor來干涉Spring創建Bean的過程。

BeanFactoryPostProcessor

BeanFactoryPostProcessor表示Bean工廠的后置處理器,其實和BeanPostProcessor類似,BeanPostProcessor是干涉Bean的創建過程,BeanFactoryPostProcessor是干涉BeanFactory的創建過程。比如,我們可以這樣定義一個BeanFactoryPostProcessor:

@Component
public class ZhouyuBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {System.out.println("加工beanFactory");}
}

我們可以在postProcessBeanFactory()方法中對BeanFactory進行加工。

FactoryBean

上面提到,我們可以通過BeanPostPorcessor來干涉Spring創建Bean的過程,但是如果我們想一個Bean完完全全由我們來創造,也是可以的,比如通過FactoryBean:

@Component
public class ZhouyuFactoryBean implements FactoryBean {@Overridepublic Object getObject() throws Exception {UserService userService = new UserService();return userService;}@Overridepublic Class<?> getObjectType() {return UserService.class;}
}

通過上面這段代碼,我們自己創造了一個UserService對象,并且它將成為Bean。但是通過這種方式創造出來的UserService的Bean,只會經過**初始化后**,其他Spring的生命周期步驟是不會經過的,比如依賴注入。

有同學可能會想到,通過@Bean也可以自己生成一個對象作為Bean,那么和FactoryBean的區別是什么呢?其實在很多場景下他倆是可以替換的,但是站在原理層面來說的,區別很明顯,@Bean定義的Bean是會經過完整的Bean生命周期的。

ExcludeFilter和IncludeFilter

這兩個Filter是Spring掃描過程中用來過濾的。ExcludeFilter表示排除過濾器,IncludeFilter表示包含過濾器。

比如以下配置,表示掃描com.zhouyu這個包下面的所有類,但是排除UserService類,也就是就算它上面有@Component注解也不會成為Bean。

@ComponentScan(value = "com.zhouyu",excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)})
public class AppConfig {
}

再比如以下配置,就算UserService類上沒有@Component注解,它也會被掃描成為一個Bean。

@ComponentScan(value = "com.zhouyu",includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = UserService.class)})
public class AppConfig {
}

FilterType分為:

  1. ANNOTATION:表示是否包含某個注解
  2. ASSIGNABLE_TYPE:表示是否是某個類
  3. ASPECTJ:表示否是符合某個Aspectj表達式
  4. REGEX:表示是否符合某個正則表達式
  5. CUSTOM:自定義

在Spring的掃描邏輯中,默認會添加一個AnnotationTypeFilter給includeFilters,表示默認情況下Spring掃描過程中會認為類上有@Component注解的就是Bean

EnvironmentAware

凡注冊到Spring容器內的bean,實現了EnvironmentAware接口重寫setEnvironment方法后,在工程啟動時可以獲得application.properties的配置文件配置的屬性值。

public class DataSourceAutoConfig implements EnvironmentAware {@Overridepublic void setEnvironment(Environment environment) {String prefix = "router.jdbc.datasource.";dbCount = Integer.valueOf(environment.getProperty(prefix + "dbCount"));tbCount = Integer.valueOf(environment.getProperty(prefix + "tbCount"));String dataSources = environment.getProperty(prefix + "list");for (String dbInfo : dataSources.split(",")) {Map<String, Object> dataSourceProps = PropertyUtil.handle(environment, prefix + dbInfo, Map.class);dataSourceMap.put(dbInfo, dataSourceProps);}}

AbstractRoutingDataSource

動態數據源配置需要繼承 AbstractRoutingDataSource 實現 determineCurrentLookupKey 方法。

public class DynamicDataSource extends AbstractRoutingDataSource {@Overrideprotected Object determineCurrentLookupKey() {return "db" + DBContextHolder.getDBKey();}
}

ApplicationContext

ApplicationContext,繼承于 ListableBeanFactory,也就繼承了關于 BeanFactory 方法,比如一些 getBean 的方法。另外 ApplicationContext 本身是 Central 接口,但目前還不需要添加一些獲取 ID 和父類上下文,所以暫時沒有接口方法的定義。

public interface ApplicationContext extends ListableBeanFactory {
}

ConfigurableApplicationContext

ApplicationListener

ApplicationContextAware

public class SpringContextUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext)throws BeansException {SpringContextUtils.applicationContext = applicationContext;}public static Object getBean(String name) {return applicationContext.getBean(name);}public static <T> T getBean(Class<T> requiredType) {return applicationContext.getBean(requiredType);}public static <T> T getBean(String name, Class<T> requiredType) {return applicationContext.getBean(name, requiredType);}public static boolean containsBean(String name) {return applicationContext.containsBean(name);}public static boolean isSingleton(String name) {return applicationContext.isSingleton(name);}public static Class<? extends Object> getType(String name) {return applicationContext.getType(name);}
}

InitializingBean

InitializingBean接口為bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是繼承該接口的類,在初始化bean的時候都會執行該方法。

public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {@Overridepublic void afterPropertiesSet() {}
}

BeanFactoryAware

beanFactory讓你可以不依賴注入方式,隨意的讀取IOC容器里面的對象,不過beanFactory本身還是要注入的。

public class BeanFactorys implements BeanFactoryAware {private BeanFactory beanFactory;@Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory = beanFactory;}public void init() {Object service = this.beanFactory.getBean("service");}
}

ImportBeanDefinitionRegistrar

作用:目的是實現bean的動態注入。

實現這個接口的類可以在使用@Configuration的地方引入,然后實現動態的bean注入到spring容器,這個是在@Bean注解定義bean 后動態的注入bean

AutoConfigurationPackages

作用是將添加該注解的類所在的package 作為自動配置package進行管理。

可以通過AutoConfigurationPackages工具類獲取自動配置package列表。

FactoryBean

MetadataReader

https://blog.csdn.net/f641385712/article/details/88765470

BeanPostProcessor

**用于修改新實例化 Bean 對象的擴展點,**BeanPostProcessor 是在 Bean 對象實例化之后修改 Bean 對象,也可以替換 Bean 對象。

BeanFactoryPostProcess

允許自定義修改 BeanDefinition 屬性信息

public interface BeanFactoryPostProcessor {/*** 在所有的 BeanDefinition 加載完成后,實例化 Bean 對象之前,提供修改 BeanDefinition 屬性的機制** @param beanFactory* @throws BeansException*/void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83186.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83186.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83186.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在vue中this.$emit有哪些作用,事件監控具體含義,以及這些子組件能封裝哪些功能組件

this.$emit 的作用 this.$emit 的作用是觸發一個自定義事件&#xff0c;并將數據傳遞給父組件。父組件可以通過 v-on&#xff08;或 &#xff09;監聽這個事件&#xff0c;并在事件觸發時執行相應的處理函數。 this.content 的作用 this.content 是子組件的 props&#xff0…

前端流行框架Vue3教程:16. 組件事件配合`v-model`使用

組件事件配合v-model使用 如果是用戶輸入&#xff0c;我們希望在獲取數據的同時發送數據配合v-model 來使用&#xff0c;幫助理解組件間的通信和數據綁定。 &#x1f9e9; 第一步&#xff1a;創建子組件&#xff08;SearchComponent.vue&#xff09; 這個組件用于處理用戶的搜…

《Navicat之外的新選擇:實測支持國產數據庫的SQLynx核心功能解析》

數據庫工具生態的新變量 在數據庫管理工具領域&#xff0c;Navicat長期占據開發者心智。但隨著國產數據庫崛起和技術信創需求&#xff0c;開發者對工具的兼容性、輕量化和本土化適配提出了更高要求。近期體驗了一款名為SQLynx的國產數據庫管理工具&#xff08;麥聰旗下產品&am…

AgenticSeek開源的完全本地的 Manus AI。無需 API,享受一個自主代理,它可以思考、瀏覽 Web 和編碼,只需支付電費。

?一、軟件介紹 文末提供程序和源碼下載 AgenticSeek開源的完全本地的 Manus AI。無需 API&#xff0c;享受一個自主代理&#xff0c;它可以思考、瀏覽 Web 和編碼&#xff0c;只需支付電費。這款支持語音的 AI 助手是 Manus AI 的 100% 本地替代品 &#xff0c;可自主瀏覽網頁…

vue3.0的name屬性插件——vite-plugin-vue-setup-extend

安裝 這個由于是在開發環境下的一個插件 幫助我們支持name屬性 所以需要是-D npm i vite-plugin-vue-setup-extend -D在pasckjson中無法注釋每個插件的用處 可以在vscode中下載一個JsonComments這樣可以在json中添加注釋方便日后維護和查閱API 引入 在vite.config.js中 im…

Linux基礎 -- 在內存中使用chroot修復eMMC

Linux基礎 – 在內存中使用chroot修復eMMC 概述 本教程將介紹如何在Linux系統中&#xff0c;使用chroot在內存中構建一個臨時系統&#xff0c;并在不依賴原有系統的情況下修復eMMC&#xff08;如/dev/mmcblk2&#xff09;磁盤。該方法適用于嵌入式系統修復、磁盤清理以及離線…

人工智能、深度學習、機器學習的聯系與區別

定義 人工智能&#xff08;AI - Artificial Intelligence&#xff09; &#xff1a;是研究、開發用于模擬、延伸和擴展人的智能的理論、方法、技術及應用系統的一門新的技術科學。它旨在讓計算機能夠像人類一樣思考、學習和決策&#xff0c;涉及到諸如計算機視覺、自然語言處理…

web第二次課后作業--設計一個注冊登錄系統

一、頁面展示 登錄頁面 提交頁面 二、代碼 2.1 登錄頁面 <% page language"java" contentType"text/html; charsetUTF-8"pageEncoding"UTF-8"%><html> <head><meta http-equiv"Content-Type" content"…

電腦桌面便簽哪個好?2025年電腦免費用的便簽軟件推薦

我們都知道&#xff0c;一個優秀的桌面便簽軟件可以成為提高效率的得力助手。無論是記錄臨時靈感、管理待辦事項&#xff0c;還是提醒重要日程&#xff0c;合適的便簽工具都能讓您的數字生活更加有序。本文將為您介紹2025年最值得推薦的免費電腦桌面便簽軟件&#xff0c;從Wind…

【SPIN】用Promela驗證順序程序:從斷言到SPIN實戰(SPIN學習系列--2)

你寫了一段自認為“天衣無縫”的程序&#xff0c;但如何確保它真的沒有bug&#xff1f;靠手動測試&#xff1f;可能漏掉邊界情況&#xff1b;靠直覺&#xff1f;更不靠譜&#xff01;這時候&#xff0c;Promela SPIN組合就像程序的“顯微鏡”——用形式化驗證技術&#xff0c;…

LabVIEW中樣條插值實現及應用

在 LabVIEW 編程環境下&#xff0c;B - 樣條插值是處理數據擬合與曲線平滑的重要工具。它憑借靈活的特性和良好的數學性質&#xff0c;在眾多工程領域中發揮著關鍵作用&#xff0c;能夠高效地根據離散數據點生成平滑連續的曲線&#xff0c;為數據分析和處理提供了有力支持。 一…

【油藏地球物理正演軟件ColchisFM】基于數據驅動的油藏參數疊前地震反演研究進展

科吉思基于油藏地球物理參數的正演軟件ColchisFM&#xff0c;有機融合了巖石物理正演與地震正演&#xff0c;具有良好的適用性和便捷性&#xff0c;在業內已經廣泛使用。當用戶在做正演模擬的同時&#xff0c;自然會聯想到是否可以直接開展油藏地球物理參數反演呢&#xff1f;答…

互聯網大廠Java求職面試:AI與大模型集成的云原生架構設計

互聯網大廠Java求職面試&#xff1a;AI與大模型集成的云原生架構設計 引言 在現代互聯網企業中&#xff0c;AI與大模型技術的應用已經成為不可或缺的一部分。特別是在短視頻平臺、電商平臺和金融科技等領域&#xff0c;如何高效地將大模型集成到現有的云原生架構中是一個巨大…

Web GIS可視化地圖框架Leaflet、OpenLayers、Mapbox、Cesium、ArcGis for JavaScript

Mapbox、OpenLayers、Leaflet、ArcGIS for JavaScript和Cesium是五種常用的Web GIS地圖框架&#xff0c;它們各有優缺點&#xff0c;適用于不同的場景。還有常見的3d庫和高德地圖、百度地圖。 1. Mapbox 官網Mapbox Gl JS案列&#xff1a;https://docs.mapbox.com/mapbox-gl-…

專項智能練習(加強題型)-DA-02

2. 單選題 近年來&#xff0c;“斜杠青年”成為很多人的時尚追求。它指的是一群不再滿足“專一職業”生活方式&#xff0c;而選擇擁有多重職業和身份的多元生活人群。對此&#xff0c;有人認為&#xff0c;新產業新技術新業態不斷更迭&#xff0c;激烈的競爭促使青年人不斷進行…

使用gitbook 工具編寫接口文檔或博客

步驟一&#xff1a;在項目目錄中初始化一個 GitBook 項目 mkdir mybook && cd mybook git init npm init -y步驟二&#xff1a;添加書籍結構&#xff08;如 book.json, README.md&#xff09; echo "# 我的書" > README.md echo "{}" > bo…

Malformed input or input contains unmappable characters解決

JDK 17 文件上傳編碼異常解決方案技術文檔 1. 問題背景 在 JDK 17 環境下&#xff0c;文件上傳過程中可能拋出 Malformed input or input contains unmappable characters 錯誤。此問題通常由以下原因觸發&#xff1a; 文件路徑/名稱包含非 ASCII 字符&#xff08;如中文、日…

MyBatis 的分頁插件 c

前言 大型項目的數據體量很大&#xff0c;在前端界面展示時為保障展示效果&#xff0c;會要求接口快速返回&#xff0c;這時候后端會選擇分頁獲取數據&#xff0c;只傳遞要查詢的頁碼數據。這就避免了大多問題&#xff0c;達到快速返回的效果。 常用的分頁有2種&#xff1a; …

Linux:理解文件系統

1.理解硬件 1.1磁盤 機械磁盤是計算機中的?個機械設備 磁盤--- 外設 慢 容量?&#xff0c;價格便宜 1.2磁盤物理結構 1.3磁盤的存儲結構 扇區&#xff1a;是磁盤存儲數據的基本單位&#xff0c;512字節&#xff0c;塊設備 如何定位?個扇區呢&#xff1f; 確定磁頭要訪…

用 openssl 測試 tls 連接

以 baidu 為例&#xff0c;命令行為&#xff1a; openssl s_client -tlsextdebug -connect baidu.com:443 得到的輸出為&#xff1a; CONNECTED(00000003) TLS server extension "renegotiation info" (id65281), len1 0000 - 00 …