【Spring4揭祕 BeanFactory】修改BeanFactory-BeanFactoryPostProcessor
一、BeanFactoryPostProcessor
當spring初始化好BenaDefinnitionMap之後,提供了一個介面BeanFactoryPostProcessor,允許我們開發者自定義的去修改BeanFactory中的內容,這也是符合“spring”的開閉原則
public interface BeanFactoryPostProcessor {
/**
* 這裡提供了修改beanFacotry的機會
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
BeanDefinitionRegistryPostProcessor繼承自BeanFactoryPostProcessor ,提供了更強大的功能。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* 這個介面繼承了postprocessor 並且將beanFactory轉成了registry能夠訪問並修改BeanDefinition。
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
二、自定義BeanFactoryPostProcessor
實現BeanFactoryPostProcessor介面即可
public class MyFactoryProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
//這裡可以呼叫ConfigurableListableBeanFactory方法對它處理
//...
System.out.println("postProcessBeanFactory處理中....");
}
}
手動呼叫BeanFactoryPostProcessor
public class Tester {
public static void main(String[] args) throws Exception {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
new MyFactoryProcessor().postProcessBeanFactory(factory);
}
}
==============輸出:============
postProcessBeanFactory處理中....
三、Spring常用BeanFactoryPostProcessor
spring也提供了不少BeanFactoryPostProcessor的實現,最常用的幾個:PropertySourcesPlaceholderConfigurer 、 CustomerEditorConfigurer、 PropertyOverrideConfigurer等。
3.1 佔位符處理器
【PropertyPlaceholderConfigurer】可以從屬性檔案、屬性類獲取屬性
【PreferencesPlaceholderConfigurer】對屬性來源具有優先順序順序
【PropertySourcesPlaceholderConfigurer 】提供了比PropertyPlaceholderConfigurer更強大的功能,可以從屬性檔案、屬性類、環境、PropertySources等獲取屬性(Spring3.1以後推薦使用這個類)
【PropertyOverrideConfigurer】可以讀取帶有bean id的屬性直接向bean注入屬性,而不需要配置
PropertySourcesPlaceholderConfigurer
使用方法:
public class Tester {
public static void main(String[] args) throws Exception {
//建立一個BeanFactory,並註冊一個bean,bean的類名用佔位符表示
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
RootBeanDefinition beanDefinition = new RootBeanDefinition("${beanName}");//佔位符
beanDefinition.setScope("${scop}");//佔位符
factory.registerBeanDefinition("myBean", beanDefinition);
//建立一個PropertySourcesPlaceholderConfigurer,
//並加入含有佔位符字串對應的 MutablePropertySources
PropertySourcesPlaceholderConfigurer configurer
= new PropertySourcesPlaceholderConfigurer();
Map<String, Object> map = new HashMap<>();
map.put("beanName", "Tester");//佔位符對應
map.put("scop", RootBeanDefinition.SCOPE_PROTOTYPE);//佔位符對應“prototype”
MutablePropertySources sources = new MutablePropertySources();
sources.addLast(new MapPropertySource("abc", map));
configurer.setPropertySources(sources);
//對 BeanFactory增強,會替換掉佔位符
configurer.postProcessBeanFactory(factory);
//獲取這個bean
System.out.println(factory.getBeanDefinition("myBean"));
System.out.println(factory.getBean("myBean"));
}
@Override
public String toString() {
return "A bean";
}
}
3.2 CustomerEditorConfigurer
java是強型別的一種語言:int,String,String[],Person等等等等。
而我們配置的xml,裡面都是字面量,也就是說,spring拿到的原始資料全部是字串。
那麼,spring是怎麼把字串轉成各種各樣的型別呢? 用 CustomEditorConfigurer,
Spring內部通過JavaBean的PropertyEditor來幫助進行String型別到其他型別的轉換工作。只要為每種物件型別提供一個PropertyEditor,就可以根據該物件型別取得與其相對應的PropertyEditor來做具體的型別轉換。Spring容器內部在做具體的型別轉換的時候,會採用JavaBean框架內預設的PropertyEditor搜尋邏輯。
3.3 ConfigurationClassPostProcessor
ConfigurationClassPostProcessor是一個BeanFactory和BeanDefinitionRegistry處理器,BeanDefinitionRegistry處理方法能處理@Configuration等註解。
通過檢視原始碼,ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry(..)內部使用ConfigurationClassParser類來處理@Configuration,@Import,@ImportResource和類內部的@Bean
如果@Import包含的Bean為ImportSelector型別。還會呼叫ImportSelector#selectImports()生成相應的Bean。
【ConfigurationClassPostProcessor基本使用】
class User{
//示例類
}
@Configuration
@Import({User.class})
public class ConfigTest {
@Bean
Date date() {
return new Date();
}
public static void main(String[] args) {
ConfigurationClassPostProcessor postProcessor = new ConfigurationClassPostProcessor();
SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
registry.registerBeanDefinition("test", new RootBeanDefinition(ConfigTest.class));
//處理BeanDefinitionRegistry
postProcessor.postProcessBeanDefinitionRegistry(registry);
//輸出結果
System.out.println(registry.getBeanDefinition("test"));//可以輸出
System.out.println(registry.getBeanDefinition("date"));//可以輸出
System.out.println(registry.getBeanDefinition("User"));//可以輸出
}
}
【ConfigurationClassPostProcessor配合@Import/ImportSelector使用】
class User{
//示例類
}
class MySelector implements ImportSelector{
//自定義一個ImportSelector實現類
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
//會生成兩個Bean(java.util.Date和User)
return new String[]{"java.util.Date","User"};
}
}
@Configuration
@Import({MySelector.class})
public class ConfigTest {
public static void main(String[] args) {
ConfigurationClassPostProcessor postProcessor = new ConfigurationClassPostProcessor();
SimpleBeanDefinitionRegistry registry = new SimpleBeanDefinitionRegistry();
registry.registerBeanDefinition("test", new RootBeanDefinition(ConfigTest.class));
postProcessor.postProcessBeanDefinitionRegistry(registry);
System.out.println(registry.getBeanDefinition("test"));//
System.out.println(registry.getBeanDefinition("User"));//可以輸出
System.out.println(registry.getBeanDefinition("java.util.Date"));//可以輸出
}
}
相關推薦
【Spring4揭祕 BeanFactory】修改BeanFactory-BeanFactoryPostProcessor
一、BeanFactoryPostProcessor 當spring初始化好BenaDefinnitionMap之後,提供了一個介面BeanFactoryPostProcessor,允許我們開發者自定義的去修改BeanFactory中的內容,這也是符合“spr
【Spring4揭祕 基礎5】BeanDefinition及讀取、註冊
一、 BeanDefinition及其實現類 BeanDefinition介面 這個介面描述bean的結構,對應XML中的< bean >或者配置類中的@Bean 它繼承了BeanMetadataElement和AttributeAccess
【Spring原始碼分析】11-BeanFactory
BeanFactory是Spring容器實現的基礎,訪問Spring容器的根介面。每個bean都是通過string型別bean name進行標識.這邊提供了設計模式單例,原型的替代實現。如果bean name配置為單例,應用內只會獲取到一個例項。如果配置為原型,那麼可以例項化
【Spring4揭祕 基礎2】PropertySource和Enviroment
一 、抽象類PropertySource及子類 PropertySource是一個抽象類,它包含一個source和一個name。source可以是map或其他,通常是一組鍵值對。 這個類結構簡化如下: public abstract class Pro
【數據庫】修改表結構
efault span 表名 mit ren 修改字段 修改表 ble unit 一、修改字段默認值 alter table 表名 drop constraint 約束名字 ------說明:刪除表的字段的原有約束 alter table 表名 add constra
【Taro全實踐】修改radio元件的大小
需求是將radio選中後顏色改為橙色、大小改成合適大小。 1、改顏色 <Radio color='#FF7464'></Radio> 2、改大小 <Radio style={{transform:'scale(0.8)'}} color='#FF74
【python小操作】修改文件任意位置的內容
Python基本文件操作 讀入文件: f = open(‘test.txt’,’r’) 寫入文件: F = open(‘output.txt’,’w’) 注意!如果你想讀文件,卻寫錯了關鍵字,把’r’寫成’w’,並運行了程式,那麼你的文件就會變成空白的,因為你什麼都
【舊文章搬運】修改PEB,斷鏈隱藏模組成功
原文發表於百度空間,2008-7-26========================================================================== 繼續實踐之前的想法,就是斷掉如下這個結構中的雙向連結串列: typedef struct _LDR_MODULE
【.Net碼農】修改WebBrowser控制元件的核心解決方案
首先說一下原理 當下很大瀏覽器他們都是用了IE的core, 這個core只提供HTML/JS的執行和渲染,並沒有給出關於介面和一些特性上的事,所以開發自己瀏覽器如果基於IE core需要自己完成這些內容。 一張圖很好的說明了這個情況,IE瀏覽器的架構:http://msdn.microsoft.com/e
【Eclipse開發工具】 修改 Web 專案的名稱(圖文案例)
開啟Eclipse 切換到 Navigator 檢視,能顯現出專案下所有的檔案便於修改 1、修改該專案目錄下:.project檔案 <projectDescription> <n
【工作筆記0023】修改已提交的 git comments 的作者資訊(Changing author info)
最近想把本地的程式碼庫上傳到github上,結果上傳完畢後才發現作者莫名其妙變成了其他人 追究原因,發現我用的 smartgit 工具,當初在配置 Comment 資訊時,填寫了正確的 username,但卻隨便填寫了一個 useremail為“[email p
【Spring原始碼解讀】BeanFactory和FactoryBean區別及類裝載原始碼解讀
最近讀程式碼讀到Bean裝載過程,順帶上網搜了下BeanFactory和FactoryBean,發現好多文章都講的不清不楚,特此自己來整理了一份BeanFactory和FactoryBean的區別及講下bean的裝載和讀取過程的原始碼. 首先來
【Spring學習筆記】1:開發環境,BeanFactory和ApplicationContext兩類容器
開發環境 和Struts2,Hibernate一樣把下載的jar包放在WEB-INF/lib/下就可以了,最小依賴是: 其中commons-logging-*.jar是額外的,不是Spring自帶的。 BeanFactory容器 是為依賴注入(DI)
【Spring原始碼解析】—— 簡單工廠模式的BeanFactory的超簡版實現
一、什麼是簡單工廠模式 設計模式的核心是“分工”,通過分工將物件與職責劃分的更細化,進而提升系統設計的可擴充套件性,使其更容易維護。 開閉原則:對擴充套件開放,對修改關閉;要增加一個新的處理邏輯,可以開一個新的類,不要在老的上面修改 依賴倒轉原則:依賴關係從具體轉向抽象,也就是說:A
【X-Forwarded-For】WEB修改訪客IP
識別 int urn 開發 user p地址 連接 通過 light X-Forwarded-For(XFF)是用來識別通過HTTP代理或負載均衡方式連接到Web服務器的客戶端最原始的IP地址的HTTP請求頭字段。 Squid 緩存代理服務器的開發人員最早引入了這一HTTP
【Java】修改jar包class文件小記
加密 返回 .cn 代碼 要求 ges 命令 文件 定位 今天被瑤瑤要求幫忙了 他現在用的軟件裏有一個bug,因為是外國的開發者,所以要求修改是很麻煩的事。要改的東西很簡單,就是將一個函數裏錯誤的返回值修改。 拿到手的有軟件直接能運行的jar包。 一開始的想法比較簡單,就想
【第四組】交互設計文檔 || 最後修改日期:07/29/17
文件夾 發送 bar box 新頁面 添加圖片 修改 反饋 com 一、圖庫頁面 1. 圖庫:點擊後會轉入頁面一(本頁) 2. 回憶:點擊後會轉入頁面九 3. 添加圖片來源:點擊後會轉入頁面二 4. 刷新:點擊後會刷新頁面一,停留在本頁(如果新圖片,新狀態見頁面七) 5.
【SSH】---【Struts2、Hibernate5、Spring4】【散點知識】
作用域 才會 進行 namespace sci 3.2 對象關系映射 工作 XML 一、Struts21.1、Struts2的概念Struts2是一個用來開發MVC應用程序的框架,它提供了Web應用程序開發過程中的一些常見問題的解決方案: ->對來自用戶的輸入數
【代碼學習】角色添加權限的方法,先刪除,再添加。而不是用修改,這樣很方便。
方便 添加權限 public resource res bject void @override != @Overridepublic void addRoleResources(Resources[] resources, Long roleId) { Map<
【網站管理5】_講解網站後臺SEO優化和如何修改關鍵字以及關鍵詞布局
日期 布局 指數 soft blog ros seo優化 優化 www 講解網站後臺SEO優化和如何修改關鍵字以及關鍵詞布局 制作:賴忠標 QQ:392277956 1.打開後臺點擊左側邊上的欄目,點擊最後的系統-系統基本參數-站點設置 如下圖