如何在Spring中使用編碼方式動(dòng)態(tài)配置Bean詳解
bean與spring容器的關(guān)系
Bean配置信息定義了Bean的實(shí)現(xiàn)及依賴關(guān)系,Spring容器根據(jù)各種形式的Bean配置信息在容器內(nèi)部建立Bean定義注冊(cè)表,然后根據(jù)注冊(cè)表加載、實(shí)例化Bean,并建立Bean和Bean的依賴關(guān)系,最后將這些準(zhǔn)備就緒的Bean放到Bean緩存池中,以供外層的應(yīng)用程序進(jìn)行調(diào)用。
本文將給大家詳細(xì)介紹關(guān)于在Spring中使用編碼方式動(dòng)態(tài)配置Bean的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
1 DefaultListableBeanFactory
DefaultListableBeanFactory 實(shí)現(xiàn)了 ConfigurableListableBeanFactory 接口,可以通過(guò)這個(gè)類來(lái)動(dòng)態(tài)注入 Bean。為了保證注入的 Bean 也能被 AOP 增強(qiáng),我們需要實(shí)現(xiàn) Bean 的工廠后置處理器接口 BeanFactoryPostProcessor。
需要?jiǎng)討B(tài)注入的 Bean:
public class BookService { BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public BookDao getBookDao() { return bookDao; } }
實(shí)現(xiàn) Bean 的工廠后置處理器接口:
@Component public class BookServiceFactoryBean implements BeanFactoryPostProcessor { public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { DefaultListableBeanFactory factory = (DefaultListableBeanFactory) beanFactory; //Bean 定義 BeanDefinitionBuilder builder=BeanDefinitionBuilder.genericBeanDefinition (BookService.class); //設(shè)置屬性 builder.addPropertyReference("bookDao","bookDao"); //注冊(cè) Bean 定義 factory.registerBeanDefinition("bookService1",builder.getRawBeanDefinition()); //注冊(cè) Bean 實(shí)例 factory.registerSingleton("bookService2",new net.deniro.spring4.dynamic.BookService()); } }
這里假設(shè) bookDao 已注入容器(XML 或 注解方式)。
在此,我們既可以注冊(cè) Bean 的定義,也可以直接注冊(cè) Bean 的實(shí)例。
配置:
<context:component-scan base-package="net.deniro.spring4.dynamic" />
單元測(cè)試:
BookService bookService1 = (BookService) context.getBean("bookService1"); assertNotNull(bookService1); assertNotNull(bookService1.getBookDao()); BookService bookService2 = (BookService) context.getBean("bookService2"); assertNotNull(bookService2);
2 自定義標(biāo)簽
為了更好地封裝組件,增強(qiáng)組件的易用性,我們會(huì)將組件定義為標(biāo)簽。
自定義標(biāo)簽步驟為:
- 采用 XSD 描述自定義標(biāo)簽的元素屬性。
- 編寫(xiě) Bean 定義的解析器。
- 注冊(cè)自定義標(biāo)簽的解析器。
- 綁定命名空間解析器。
在 resources 中的 schema 文件夾下創(chuàng)建 bookservice.xsd
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.deniro.net/schema/service" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" targetNamespace="http://www.deniro.net/schema/service" elementFormDefault="qualified" attributeFormDefault="unqualified" > <!-- 導(dǎo)入 beans 命名空間--> <xsd:import namespace="http://www.springframework.org/schema/beans"/> <!-- 定義 book-service 標(biāo)簽--> <xsd:element name="book-service"> <xsd:complexType> <xsd:complexContent> <xsd:extension base="beans:identifiedType"> <!-- 定義 dao 屬性--> <xsd:attribute name="dao" type="xsd:string" use="required"/> </xsd:extension> </xsd:complexContent> </xsd:complexType> </xsd:element> </xsd:schema>
接著定義服務(wù)標(biāo)簽解析器:
public class BookServiceDefinitionParser implements BeanDefinitionParser { public BeanDefinition parse(Element element, ParserContext parserContext) { //創(chuàng)建 Bean 定義 BeanDefinitionBuilder builder=BeanDefinitionBuilder.genericBeanDefinition (BookService.class); //注入自定義的標(biāo)簽屬性 String dao=element.getAttribute("dao"); builder.addPropertyReference("bookDao",dao); //注冊(cè) Bean 定義 parserContext.registerBeanComponent(new BeanComponentDefinition(builder .getRawBeanDefinition(),"bookService")); return null; } }
然后把剛剛定義好的解析器注冊(cè)到命名空間:
public class BookServiceNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("book-service",new BookServiceDefinitionParser()); } }
接著在 resources 中創(chuàng)建 META-INF 文件夾,并新建 spring.schemas 與 spring.handlers,這兩個(gè)文件分別用于配置自定義標(biāo)簽的文檔結(jié)構(gòu)文件路徑以及解析自定義命名空間的解析器。
文件路徑
spring.handlers:
http\://www.deniro.net/schema/service=net.deniro.spring4.dynamic.BookServiceNamespaceHandler
spring.schemas:
http\://www.deniro.net/schema/service.xsd=schema/bookservice.xsd
注意: xsd 文件必須放在 resources 的子孫目錄下。
引用自定義標(biāo)簽:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:me="http://www.deniro.net/schema/service" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.deniro.net/schema/service http://www.deniro.net/schema/service.xsd "> <bean id="bookDao" class="net.deniro.spring4.dynamic.BookDao"/> <me:book-service dao="bookDao"/> </beans>
這里,我們?cè)陬^部引用了自定義標(biāo)簽,并命名為 “me”,然后就可以使用它咯O(∩_∩)O~
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- 詳解Spring-bean的循環(huán)依賴以及解決方式
- 解決SpringBoot項(xiàng)目使用多線程處理任務(wù)時(shí)無(wú)法通過(guò)@Autowired注入bean問(wèn)題
- Spring運(yùn)行時(shí)動(dòng)態(tài)注冊(cè)bean的方法
- Spring之動(dòng)態(tài)注冊(cè)bean的實(shí)現(xiàn)方法
- 詳解Spring中bean的幾種注入方式
- 關(guān)于SpringBoot獲取IOC容器中注入的Bean(推薦)
- 談?wù)勎覍?duì)Spring Bean 生命周期的理解
- Spring bean 加載執(zhí)行順序?qū)嵗馕?/a>
- 詳解Spring Bean的循環(huán)依賴解決方案
- 關(guān)于Spring中Bean的創(chuàng)建進(jìn)行更多方面的控制
相關(guān)文章
Elasticsearch倒排索引詳解及實(shí)際應(yīng)用中的優(yōu)化
Elasticsearch(ES)使用倒排索引來(lái)加速文本的搜索速度,倒排索引之所以高效,主要是因?yàn)樗淖兞藬?shù)據(jù)的組織方式,使得查詢操作可以快速完成,這篇文章主要給大家介紹了關(guān)于Elasticsearch倒排索引詳解及實(shí)際應(yīng)用中優(yōu)化的相關(guān)資料,需要的朋友可以參考下2024-08-08SpringSecurity的防Csrf攻擊實(shí)現(xiàn)代碼解析
這篇文章主要介紹了SpringSecurity的防Csrf攻擊實(shí)現(xiàn)代碼解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03Hibernate的一對(duì)一,一對(duì)多/多對(duì)一關(guān)聯(lián)保存的實(shí)現(xiàn)
本文主要介紹了Hibernate的一對(duì)一,一對(duì)多/多對(duì)一關(guān)聯(lián)保存的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的很詳細(xì),感興趣的可以了解一下2021-09-09Java中轉(zhuǎn)義字符反斜杠\的代替方法及repalceAll內(nèi)涵解析
這篇文章主要介紹了Java中轉(zhuǎn)義字符反斜杠\的代替方法及repalceAll內(nèi)涵解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08idea查看properties中文變成unicode碼的解決方案
這篇文章主要介紹了idea查看properties中文變成unicode碼的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-06-06javaDSL簡(jiǎn)單實(shí)現(xiàn)示例分享
DSL領(lǐng)域定義語(yǔ)言,用來(lái)描述特定領(lǐng)域的特定表達(dá)。比如畫(huà)圖從起點(diǎn)到終點(diǎn);路由中的從A到B。這是關(guān)于畫(huà)圖的一個(gè)簡(jiǎn)單實(shí)現(xiàn)2014-03-03詳解Spring mvc DispatchServlet 實(shí)現(xiàn)機(jī)制
本篇文章主要介紹了詳解Spring mvc DispatchServlet 實(shí)現(xiàn)機(jī)制,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-09-09