动态加载spring xml配置

Posted

技术标签:

【中文标题】动态加载spring xml配置【英文标题】:Load spring xml config dynamically 【发布时间】:2016-09-19 14:40:44 【问题描述】:

在 spring 应用程序启动时,我想扫描计算机上的路径,找到 jar 文件并从其中的 xml 配置文件构建 spring 应用程序上下文。一切都可以将 jar 文件添加到类路径并制作 ApplicationContext。但我无法从新的上下文中找到任何豆子。所有需要的依赖项都在计算机上特定路径中的 jar 文件中可用(通过 maven copier 插件),期望那些在基本 spring 项目中的依赖项(例如 spring 依赖项本身)。 代码是(Kotlin 语言):

var loader = URLClassLoader(arrayOf(entry.toFile().toURL()), Thread.currentThread().contextClassLoader)
...
val context = ClassPathXmlApplicationContext("classpath*:/$name")//name is xml file. I'm sure the address in classpath is right. context is not creating when the address in wrong. for example: classpath://$name
val services = context.getBeanNamesForType(IService::class.java)//services is empty

我尝试了许多其他方法来加载 xml,但都没有成功。例如:

val beans = DefaultListableBeanFactory(applicationContext)
val reader = XmlBeanDefinitionReader(beans)
reader.beanClassLoader = loader
reader.resourceLoader = resourceLoader
reader.setValidationMode(XmlBeanDefinitionReader.VALIDATION_XSD)
jarFile.getInputStream(jarEntry).use 
    reader.loadBeanDefinitions(EncodedResource(InputStreamResource(it)))

beans.preInstantiateSingletons()

jar 文件中的 xml 如下所示:

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:context="http://www.springframework.org/schema/context"
   xsi:schemaLocation="http://www.springframework.org/schema/context
      http://www.springframework.org/schema/context/spring-context-3.0.xsd
      http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="classpath*:/xxx-logic-context.xml"/>
<context:annotation-config/>
<context:component-scan base-package="aa.bbb.ccc.server"/>
</beans>

这真的很有趣:当我使用包扫描功能定义常规 Bean 时,我可以在某种代码中获取 bean

【问题讨论】:

context:component-scan 使用与URLClassLoader 不兼容的 MAGIC。没有运气。 @talex 但我在常规的 Spring Boot 应用程序或简单的 Spring 应用程序中使用了具有完全相同 xml 的 ClassPathXmlApplicationContext(具有包扫描和调度功能)。唯一不同的是添加类加载器。 spring 如何在常规应用程序中添加对其他 XML 的导入?它必须有一个解决方案。 不幸的是。对于 MAGIC,它经常发生。原因是 Java 没有枚举包中的类和子包的功能,component-scan 依赖于此功能。当前实现使用将jar 文件读取为简单zip 并获取类列表的技巧。但它只适用于默认的类加载器。理论上可以为其他 ClassLoader 实现这一点,但还没有人这样做。 @talex 感谢您的回答。我修好了。 【参考方案1】:

@talex 的精彩回答指导了我。我通过设置当前的类加载器来修复它:

val loader = URLClassLoader(arrayOf(entry.toFile().toURL()), Thread.currentThread().contextClassLoader)
Thread.currentThread().contextClassLoader = loader

【讨论】:

以上是关于动态加载spring xml配置的主要内容,如果未能解决你的问题,请参考以下文章

动态加载log4j.xml 文件

spring加载xml的六种方式

spring动态加载(刷新)配置文件 [复制链接]

spring篇-(ssm自定义zookeeperPropertySource实现动态配置的加载)

spring框架中多数据源创建加载并且实现动态切换的配置实例代码

在运行时将 xml 配置文件动态加载到 Flex4/Flash 电影中的最佳方法?