您好,登錄后才能下訂單哦!
bean與spring容器的關系
Bean配置信息定義了Bean的實現及依賴關系,Spring容器根據各種形式的Bean配置信息在容器內部建立Bean定義注冊表,然后根據注冊表加載、實例化Bean,并建立Bean和Bean的依賴關系,最后將這些準備就緒的Bean放到Bean緩存池中,以供外層的應用程序進行調用。
本文將給大家詳細介紹關于在Spring中使用編碼方式動態配置Bean的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。
1 DefaultListableBeanFactory
DefaultListableBeanFactory 實現了 ConfigurableListableBeanFactory 接口,可以通過這個類來動態注入 Bean。為了保證注入的 Bean 也能被 AOP 增強,我們需要實現 Bean 的工廠后置處理器接口 BeanFactoryPostProcessor。
需要動態注入的 Bean:
public class BookService { BookDao bookDao; public void setBookDao(BookDao bookDao) { this.bookDao = bookDao; } public BookDao getBookDao() { return bookDao; } }
實現 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 自定義標簽
為了更好地封裝組件,增強組件的易用性,我們會將組件定義為標簽。
自定義標簽步驟為:
在 resources 中的 schema 文件夾下創建 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) { //創建 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 中創建 META-INF 文件夾,并新建 spring.schemas 與 spring.handlers,這兩個文件分別用于配置自定義標簽的文檔結構文件路徑以及解析自定義命名空間的解析器。
文件路徑
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~
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。