2016-09-19 3 views
0

В момент запуска весеннего приложения я хочу сканировать путь на компьютере, найти файлы jar и создать контекст приложения Spring из xml-конфигурационных файлов внутри них. Все в порядке, чтобы добавить файл jar в путь к классам и создать ApplicationContext. Но я не могу найти никаких компонентов из нового контекста. Все необходимые зависимости доступны в файлах jar в определенном пути на компьютере (через плагин maven copier), ожидайте те зависимости, которые находятся в базовом проекте Spring (например, сама пружина). Код (В Котлин языке):Динамически загружать весну xml config

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() 

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> 

Это действительно интересно: Когда я определяю регулярные бобы вместо используя пакет функцию просмотрят, я могу получить боб в своем роде код

+0

'context: component-scan' use MAGIC, который несовместим с' URLClassLoader'. Не повезло. – talex

+0

@talex, но я использовал ClassPathXmlApplicationContext с точно таким же xml (с функциями сканирования пакетов и расписания) в обычных весенних загрузочных приложениях или простых весенних приложениях. Единственным отличием является добавление загрузчика классов. Как весна добавляет импорт в другие XML-файлы в обычных приложениях? У него должно быть решение. –

+1

К сожалению. С MAGIC это происходит очень часто. Смысл заключается в том, что Java не имеет функции для перечисления классов и подпакетов в пакете, а 'component-scan' зависит от этой функции. Текущая реализация использует трюк, который читает 'jar' файлы как простые' zip' и получает список классов. Но он работает только с загрузчиком класса по умолчанию. Теоретически это можно реализовать для другого ClassLoader, но никто этого не делал. – talex

ответ

1

Отличный ответ от @talex. Я установил его, установив текущий загрузчик классов:

val loader = URLClassLoader(arrayOf(entry.toFile().toURL()), Thread.currentThread().contextClassLoader) 
Thread.currentThread().contextClassLoader = loader 
Смежные вопросы