如何在Spring中使用編碼方式動態(tài)配置Bean詳解
bean與spring容器的關系

Bean配置信息定義了Bean的實現(xiàn)及依賴關系,Spring容器根據(jù)各種形式的Bean配置信息在容器內(nèi)部建立Bean定義注冊表,然后根據(jù)注冊表加載、實例化Bean,并建立Bean和Bean的依賴關系,最后將這些準備就緒的Bean放到Bean緩存池中,以供外層的應用程序進行調(diào)用。
本文將給大家詳細介紹關于在Spring中使用編碼方式動態(tài)配置Bean的相關內(nèi)容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。
1 DefaultListableBeanFactory
DefaultListableBeanFactory 實現(xiàn)了 ConfigurableListableBeanFactory 接口,可以通過這個類來動態(tài)注入 Bean。為了保證注入的 Bean 也能被 AOP 增強,我們需要實現(xiàn) Bean 的工廠后置處理器接口 BeanFactoryPostProcessor。
需要動態(tài)注入的 Bean:
public class BookService {
BookDao bookDao;
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public BookDao getBookDao() {
return bookDao;
}
}
實現(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);
//設置屬性
builder.addPropertyReference("bookDao","bookDao");
//注冊 Bean 定義
factory.registerBeanDefinition("bookService1",builder.getRawBeanDefinition());
//注冊 Bean 實例
factory.registerSingleton("bookService2",new net.deniro.spring4.dynamic.BookService());
}
}
這里假設 bookDao 已注入容器(XML 或 注解方式)。
在此,我們既可以注冊 Bean 的定義,也可以直接注冊 Bean 的實例。
配置:
<context:component-scan base-package="net.deniro.spring4.dynamic" />
單元測試:
BookService bookService1 = (BookService) context.getBean("bookService1");
assertNotNull(bookService1);
assertNotNull(bookService1.getBookDao());
BookService bookService2 = (BookService) context.getBean("bookService2");
assertNotNull(bookService2);
2 自定義標簽
為了更好地封裝組件,增強組件的易用性,我們會將組件定義為標簽。
自定義標簽步驟為:
- 采用 XSD 描述自定義標簽的元素屬性。
- 編寫 Bean 定義的解析器。
- 注冊自定義標簽的解析器。
- 綁定命名空間解析器。
在 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"
>
<!-- 導入 beans 命名空間-->
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
<!-- 定義 book-service 標簽-->
<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>
接著定義服務標簽解析器:
public class BookServiceDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
//創(chuàng)建 Bean 定義
BeanDefinitionBuilder builder=BeanDefinitionBuilder.genericBeanDefinition
(BookService.class);
//注入自定義的標簽屬性
String dao=element.getAttribute("dao");
builder.addPropertyReference("bookDao",dao);
//注冊 Bean 定義
parserContext.registerBeanComponent(new BeanComponentDefinition(builder
.getRawBeanDefinition(),"bookService"));
return null;
}
}
然后把剛剛定義好的解析器注冊到命名空間:
public class BookServiceNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("book-service",new BookServiceDefinitionParser());
}
}
接著在 resources 中創(chuàng)建 META-INF 文件夾,并新建 spring.schemas 與 spring.handlers,這兩個文件分別用于配置自定義標簽的文檔結(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 的子孫目錄下。
引用自定義標簽:
<?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>
這里,我們在頭部引用了自定義標簽,并命名為 “me”,然后就可以使用它咯O(∩_∩)O~
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
- 詳解Spring-bean的循環(huán)依賴以及解決方式
- 解決SpringBoot項目使用多線程處理任務時無法通過@Autowired注入bean問題
- Spring運行時動態(tài)注冊bean的方法
- Spring之動態(tài)注冊bean的實現(xiàn)方法
- 詳解Spring中bean的幾種注入方式
- 關于SpringBoot獲取IOC容器中注入的Bean(推薦)
- 談談我對Spring Bean 生命周期的理解
- Spring bean 加載執(zhí)行順序?qū)嵗馕?/a>
- 詳解Spring Bean的循環(huán)依賴解決方案
- 關于Spring中Bean的創(chuàng)建進行更多方面的控制
相關文章
如何通過java實現(xiàn)highcharts導出圖片至excel
這篇文章主要介紹了如何通過java實現(xiàn)highcharts導出圖片至excel。文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,下面我們就來一起學習一下吧2019-06-06
使用IDEA直接連接MySQL數(shù)據(jù)庫的方法
這篇文章主要介紹了如何使用IDEA直接連接MySQL數(shù)據(jù)庫,首先需要新建一個空項目,第一次連接 需要先下載驅(qū)動,文中給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧2024-04-04
JVM教程之Java代碼編譯和執(zhí)行的整個過程(二)
這篇文章主要介紹了JVM學習筆記第二篇,關于Java代碼編譯和執(zhí)行的整個過程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03

