Весенний загрузочный мультитенантный код с изолированной клиент-изолированной изоляцией - PullRequest
0 голосов
/ 05 июня 2019

Я создаю весеннее загрузочное приложение, которое должно поддерживать несколько клиентов. В настоящее время у меня есть общая логика, определенная в родительском проекте, и настройки в дочернем проекте. В некоторых случаях клиенты могут запрашивать дополнительные функции или могут нуждаться в дополнительной настройке существующей функции, которая определена для этого дочернего элемента с помощью аннотации @Primary. Идея состоит в том, чтобы разделить основную логику и настройки.

В настоящее время мы создаем разные ветви для разных клиентов в дочернем проекте, и настройки выполняются в тех, которые не являются лучшим решением. Поскольку число клиентов не увеличится, число филиалов также не увеличится.

Мне нужен один код, в котором я буду определять все настройки для всех клиентов, а функции, доступные каждому клиенту, должны быть управляемыми.

Я знаю, что этого можно добиться с помощью профилей. Но все же, даже в этом случае, я должен определить профили для всех аннотаций компонентов, которые являются громоздкими.

Так что недавно у меня появилась идея использовать @Componentscan со свойством для управления клиентской логикой со следующей структурой каталогов.

Родитель:

.
└── src
    └── main
        └── java
            ├── com.test.parent.controller
            ├── com.test.parent.dao
            └── com.test.parent.service

Ребенок:

.
└── src
    └── main
        └── java
            ├── com.test.child.client1.controller
            ├── com.test.child.client1.dao
            ├── com.test.child.client1.service
            ├── com.test.child.client2.controller
            ├── com.test.child.client2.dao
            ├── com.test.child.client2.service
            ├── com.test.child.client3.controller
            ├── com.test.child.client3.dao
            └── com.test.child.client3.service

Mainclass.java

package com.test.child;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;

@SpringBootApplication
@ComponentScan(basePackages = { "com.test.parent.*","com.test.child.${clientname:default}.*" })
public class MainClass {

    public static void main(String[] args) {
        SpringApplication.run(MainClass.class, args);
    }

}

Но даже, в этом случае я контролирую настройку клиентов с помощью свойства clientname, и существует риск раскрытия настройки других клиентов путем передачи имени другого клиента.

  • Можно ли контролировать пакеты или бизнес-логика должна быть включена или исключена в течение mvn package или mvn install сама при условии, что код остается единичным? т.е. изолировать логику во время самого построения вместо времени выполнения.
  • Кажется, плагин maven-compiler-plugin предоставляет такую ​​возможность, указав includes вместе с pattern. Но как сделать то же самое в spring-boot-maven-plugin, чтобы сборка контролировалась , передавая свойство во время mvn package или mvn install?

Так что в основном я выгляжу как фильтр, который поддерживает шаблон для включения / исключения пакета / кода во время жизненного цикла сборки mvn.

Не уверен, что <resources><resource>..<\resources><\resource> может использоваться для фильтрации кода отдельно от ресурсов.

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Механизм автоконфигурации Spring Boot имеет возможность автоматически обнаруживать классы автоконфигурации, которые находятся в пути к классам во время выполнения, и импортировать их в контекст (иногда используя условия, чтобы решить, делать ли это).

В вашем случае кажется, что основательный подход - написать и упаковать ваше общее приложение Spring Boot в единый общий jar-файл.Тогда конкретный код каждого клиента будет жить в «плагине», который объявляет Client1AutoConfiguration;при запуске приложения скажите Boot также загрузить jar плагина .

Если в главном банке есть значения по умолчанию, которые необходимо переопределить в плагинах, используйте @ConditionalOnMissingBean (см. DataSourceAutoConfiguration для хорошего примера) и аннотируйте классы автоконфигурации вашего плагина с помощью @AutoConfigureBefore(MainAutoConfiguration.class).

0 голосов
/ 06 июня 2019

Наконец разобрался.Я должен использовать maven-compiler-plugin вместе с spring-boot-maven-plugin, чтобы исключить файлы или папки.Поскольку spring-boot-maven-plugin можно использовать только для исключения devtools, артефактов или групповых идентификаторов, maven-compiler-plugin используется для исключения / включения файлов / папок.

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>${spring.boot.version}</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>
   ........
   ........
   ........
   <properties>
      <java.version>1.8</java.version>
      <client.name>defaultclientname</client.name>
   </properties>
   <build>
      <plugins>
         <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
         </plugin>
         <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
               <includes>
                  <include>com/test/child/MainClass.java</include>
                  <!--Spring boot mainclass entry-->
                  <include>com/test/child/${client.name}/**</include>
                  <!--Includes only the specified client.-->
               </includes>
            </configuration>
         </plugin>
      </plugins>
   </build>
</project>

Поскольку client.name определено в свойстве, оно становится значением по умолчаниюзначение и то же самое можно переопределить во время сборки, передав соответствующее значение, например mvn clean package -Dclient.name=client1.

Теперь нет необходимости контроля во время выполнения, и настройки клиента полностью изолированы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...