Как динамически загружать Spring контроллеры - PullRequest
1 голос
/ 22 мая 2019

У меня есть приложение Spring Boot, в котором размещен REST API.

В зависимости от того, какие файлы развертываются, я хочу иметь возможность загружать дополнительные контроллеры из того, что по сути является «подключаемым» JAR-файлом.

Например, я хотел бы иметь возможность сделать что-то вроде этого:

java -jar myapp.jar -Dplugins.directory=/opt/myapp/plugins

Возможно ли это?

Примечание: они не будут загружены налетать;после развертывания набор плагинов останется фиксированным.Мне нужен один jar приложения, который остается одинаковым при каждом развертывании, и поведение приложения будет определяться плагинами, которые развернуты рядом с ним.

1 Ответ

0 голосов
/ 23 мая 2019

может не на 100% удовлетворить ваши требования. У меня есть два предложения.

легкий. java -jar stackoverflow-1.0-SNAPSHOT.jar --spring.profiles.active=prod и установите другое значение "@Profile" на вашем контроллере.

@RestController
@Profile("prod")
public class URLOneController {

@PostMapping(value = "/url", consumes="application/json", produces="application/json")
public ResponseEntity<HttpStatus> insertClaim(@RequestBody String messageBody) {
    return new ResponseEntity<>(HttpStatus.OK);
}

}

второе предложение, динамическая загрузка beanDefiniton.

@Configuration
@ConditionalOnProperty(name="external.controller.enable",havingValue = "true")
public class ExternalClassDefinitionProcessor  implements 
BeanDefinitionRegistryPostProcessor {

@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();


    Class<?> aClass = null;
    try {
        aClass = contextClassLoader.loadClass("com.jin.learn.demo.UrlOneController");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }

    BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
            .genericBeanDefinition(aClass);

    beanDefinitionBuilder.addPropertyReference("personDao", "personDao");

    BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder
            .getRawBeanDefinition();
    registry.registerBeanDefinition("UrlOneController", 
personManagerBeanDefinition);

}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory 
beanFactory) throws BeansException {

   }
}

упакуйте ваш контроллер в обычный jar (не используйте spring-boot-maven-plugin)

запустите ваше приложение, как эта командная строка

java -Dloader.path="lib/,config/,/home/jin/Desktop/abc/target/abc-1.0-SNAPSHOT.jar" -jar stackoverflow-1.0-SNAPSHOT.jar --external.controller.enable=true

дополнительный контроллер в abc-1.0-SNAPSHOT.jar и ваше основное приложение - stackoverflow-1.0-SNAPSHOT.jar

Советы: stackoverflow-1.0-SNAPSHOT.jar должен упаковывать zip формат.

<plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <layout>ZIP</layout>
            </configuration>
        </plugin>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...