如何在Spring中使用编码方式动态配置Bean详解

网友投稿 389 2023-02-04


如何在Spring中使用编码方式动态配置Bean详解

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 的实例。

配置:

/>

单元测试:

BookService bookService1 = (BookService) context.getBean("bookService1");

assertNotNull(bookService1);

assertNotNull(bookService1.getBookDao());

BookService bookService2 = (BookService) context.getBean("bookService2");

assertNotNull(bookService2);

2 自定义标签

为了更好地封装组件,增强组件的易用性,我们会将组件定义为标签。

自定义标签步骤为:

采用 XSD 描述自定义标签的元素属性。

编写 Bean 定义的解析器。

注册自定义标签的解析器。

绑定命名空间解析器。

在 resources 中的 schema 文件夹下创建 bookservice.xsd

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://deniro.net/schema/service"

elementFormDefault="qualified"

attributeFormDefault="unqualified"

>

接着定义服务标签解析器:

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\://deniro.net/schema/service=net.deniro.spring4.dynamic.BookServiceNamespaceHandler

spring.schemas:

http\://deniro.net/schema/service.xsd=schema/bookservice.xsd

注意: xsd 文件必须放在 resources 的子孙目录下。

引用自定义标签:

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:me="http://deniro.net/schema/service"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://deniro.net/schema/service http://deniro.net/schema/service.xsd

">

这里,我们在头部引用了自定义标签,并命名为 “me”,然后就可以使用它咯O(∩_∩)O~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

/>

单元测试:

BookService bookService1 = (BookService) context.getBean("bookService1");

assertNotNull(bookService1);

assertNotNull(bookService1.getBookDao());

BookService bookService2 = (BookService) context.getBean("bookService2");

assertNotNull(bookService2);

2 自定义标签

为了更好地封装组件,增强组件的易用性,我们会将组件定义为标签。

自定义标签步骤为:

采用 XSD 描述自定义标签的元素属性。

编写 Bean 定义的解析器。

注册自定义标签的解析器。

绑定命名空间解析器。

在 resources 中的 schema 文件夹下创建 bookservice.xsd

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://deniro.net/schema/service"

elementFormDefault="qualified"

attributeFormDefault="unqualified"

>

xmlns:xsd="http://w3.org/2001/XMLSchema"

xmlns:beans="http://springframework.org/schema/beans"

targetNamespace="http://deniro.net/schema/service"

elementFormDefault="qualified"

attributeFormDefault="unqualified"

>

接着定义服务标签解析器:

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\://deniro.net/schema/service=net.deniro.spring4.dynamic.BookServiceNamespaceHandler

spring.schemas:

http\://deniro.net/schema/service.xsd=schema/bookservice.xsd

注意: xsd 文件必须放在 resources 的子孙目录下。

引用自定义标签:

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:me="http://deniro.net/schema/service"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://deniro.net/schema/service http://deniro.net/schema/service.xsd

">

xmlns:xsi="http://w3.org/2001/XMLSchema-instance"

xmlns:me="http://deniro.net/schema/service"

xsi:schemaLocation="http://springframework.org/schema/beans http://springframework.org/schema/beans/spring-beans.xsd

http://deniro.net/schema/service http://deniro.net/schema/service.xsd

">

这里,我们在头部引用了自定义标签,并命名为 “me”,然后就可以使用它咯O(∩_∩)O~

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java适配器模式应用之电源适配器功能详解
下一篇:Java基于装饰者模式实现的染色馒头案例详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~