当前位置: 首页 > 编程笔记 >

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

笪波鸿
2023-03-14
本文向大家介绍如何在Spring中使用编码方式动态配置Bean详解,包括了如何在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 的实例。

配置:

<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 自定义html" target="_blank">标签

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

自定义标签步骤为:

  • 采用 XSD 描述自定义标签的元素属性。
  • 编写 Bean 定义的解析器。
  • 注册自定义标签的解析器。
  • 绑定命名空间解析器。

在 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~

总结

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

 类似资料:
  • 问题内容: 在上述情况下,bean中的属性随环境而变化。在开发时,config的引用更改为。并在阶段中将参考更改为。问题在检入spring文件时出现。每次签入之前,我们都必须分析config的引用。如果config的引用具有签入的值,我们可能必须解释很多问题。 有什么解决方案可以使其自动化? 注意:春季版本为2.0.1 问题答案: 使用Spring的PropertyPlaceholderConfi

  • 基本上,我想问的是:将Spring Boot自动配置的bean自动导入XML配置文件的等价物是什么? 下面是我的主要Spring Boot入口点,它只是所有文档中列出的标准类: 我主要在一个Spring集成应用程序中使用它,在这个应用程序中Java配置还没有得到很好的支持,框架的核心是基于XML配置的,但是我希望在一些集成元素中使用Spring Boot自动配置的和bean。 https://gi

  • 本文向大家介绍Spring Bean常用的的装配方式详解,包括了Spring Bean常用的的装配方式详解的使用技巧和注意事项,需要的朋友参考一下 Bean常用的装配方式有3种: 基于xml的装配 基于Annotation(注解)的装配 基于Java配置类的装配 基于xml的装配 在xml文件中配置Bean。 如果依赖很多,xml配置文件会很臃肿,后期维护、升级不方便。自动装配可解决这一问题。 基

  • 问题内容: 当我在多模块Maven项目上运行时,我总是得到以下输出: 因此,我在Google上搜索了一下,但我能找到的就是我必须添加: …到我的pom.xml。但是它已经在那里(在父目录中)。 配置了Maven的资源-插件或Maven的编译器插件也不能解决问题。 所以有什么问题? 问题答案: 好的,我发现了问题。 我使用一些报告插件。在failsafe-maven-plugin的文档中(http:

  • 问题内容: 我有一个应用程序,在application.properties中列出了许多数据源设置。我有一个可以加载这些设置的类。现在,我想从此类中获取值,并使用它们来动态创建DataSource bean。我尝试使用和实现。但是,使用时,处理似乎发生在早期-在填充我的课程之前。如何使用Spring Boot快速读取属性并动态创建bean? 这是我的application.properties的样

  • 下面是我的application.properties的样子: 和我的ConfigurationProperties类: 在这个方法的最后,我想创建一个具有这些设置的并将其添加到ApplicationContext中。但是,如果我试图通过实现并实现来实现这一点,则属性为null,我用填充的也是一样。 使用Spring Boot创建动态数据源的最佳方法是什么?