我不久前找到了解决方案,但我忘了在这里分享,所以感谢 Jan 提醒我。
我通过使用具有不同配置 (RepositoryRestMvcConfiguration) 的新 Web 应用程序上下文和作为 Spring Boot 应用程序的根应用程序上下文的公共父级创建和注册几个调度程序 servlet 来解决这个问题。为了根据类路径中包含的不同 jar 自动启用 API 模块,我模拟了 Spring Boot 或多或少的功能。
项目分为几个 gradle 模块。像这样的:
- 项目服务器
- project-api-autoconfigure
- project-module-a-api
- project-module-b-api
- ...
- project-module-n-api
模块 project-server 是主要模块。它声明了对project-api-autoconfigure的依赖,同时排除了project-api-autoconfigure对project-module-?的传递依赖。 -api 模块。
在project-server.gradle里面:
dependencies {
compile (project(':project-api-autoconfigure')) {
exclude module: 'project-module-a-api'
exclude module: 'project-module-b-api'
...
}
...
}
project-api-autoconfigure 依赖于所有 API 模块,所以在 project-api-autoconfigure.gradle 上的依赖关系如下所示:
dependencies {
compile project(':project-module-a-api')
compile project(':project-module-b-api')
...
}
project-api-autoconfigure 是我为每个 API 模块创建具有自己的 Web 应用程序上下文的调度程序 servlet bean 的地方,但是这种配置取决于每个 API 模块的配置类每个 API 模块 jar。
我创建并抽象了每个自动配置类都继承自的类:
public abstract class AbstractApiModuleAutoConfiguration<T> {
@Autowired
protected ApplicationContext applicationContext;
@Autowired
protected ServerProperties server;
@Autowired(required = false)
protected MultipartConfigElement multipartConfig;
@Value("${project.rest.base-api-path}")
protected String baseApiPath;
protected DispatcherServlet createApiModuleDispatcherServlet() {
AnnotationConfigWebApplicationContext webContext = new AnnotationConfigWebApplicationContext();
webContext.setParent(applicationContext);
webContext.register(getApiModuleConfigurationClass());
return new DispatcherServlet(webContext);
}
protected ServletRegistrationBean createApiModuleDispatcherServletRegistration(DispatcherServlet apiModuleDispatcherServlet) {
ServletRegistrationBean registration = new ServletRegistrationBean(
apiModuleDispatcherServlet,
this.server.getServletMapping() + baseApiPath + "/" + getApiModulePath() + "/*");
registration.setName(getApiModuleDispatcherServletBeanName());
if (this.multipartConfig != null) {
registration.setMultipartConfig(this.multipartConfig);
}
return registration;
}
protected abstract String getApiModuleDispatcherServletBeanName();
protected abstract String getApiModulePath();
protected abstract Class<T> getApiModuleConfigurationClass();
}
所以现在,模块 A 的自动配置类将如下所示:
@Configuration
@ConditionalOnClass(ApiModuleAConfiguration.class)
@ConditionalOnProperty(prefix = "project.moduleA.", value = "enabled")
public class ApiModuleAAutoConfiguration extends AbstractApiModuleAutoConfiguration<ApiModuleAConfiguration> {
public static final String API_MODULE_A_DISPATCHER_SERVLET_BEAN_NAME = "apiModuleADispatcherServlet";
public static final String API_MODULE_A_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "apiModuleADispatcherServletRegistration";
@Value("${project.moduleA.path}")
private String apiModuleAPath;
@Bean(name = API_MODULE_A_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet apiModuleADispatcherServlet() {
return createApiModuleDispatcherServlet();
}
@Bean(name = API_MODULE_A_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
public ServletRegistrationBean apiModuleADispatcherServletRegistration() {
return createApiModuleDispatcherServletRegistration(apiModuleADispatcherServlet());
}
@Override
protected String getApiModuleDispatcherServletBeanName() {
return API_MODULE_A_DISPATCHER_SERVLET_BEAN_NAME;
}
@Override
protected String getApiModulePath() {
return apiModuleAPath;
}
@Override
protected Class<ApiModuleAConfiguration> getApiModuleConfigurationClass() {
return ApiModuleAConfiguration.class;
}
}
现在,您的 ApiModuleAConfiguration、ApiModuleBConfiguration... 配置类将在每个 api 模块 project-module-a-api 上, project-module-b-api...
它们可以是 RepositoryRestMvcConfiguration 或者它们可以从它扩展,或者它们可以是导入 Spring Data REST 配置的任何其他配置类。
最后但并非最不重要的一点是,我在主模块 project-server 中创建了不同的 gradle 脚本,以根据传递给 gradle 的属性来加载以模拟 Maven 配置文件。每个脚本都将需要包含的 api 模块声明为依赖项。它看起来像这样:
- project-server
/profiles/
profile-X.gradle
profile-Y.gradle
profile-Z.gradle
例如,profile-X 启用 API 模块 A 和 B:
dependencies {
compile project(':project-module-a-api')
compile project(':project-module-b-api')
}
processResources {
from 'src/main/resources/profiles/profile-X'
include 'profile-x.properties'
into 'build/resources/main'
}
其他配置文件可以启用不同的 API 模块。
配置文件以这种方式从 project-server.gradle 加载:
loadProfile()
processResources {
include '**/*'
exclude 'profiles'
}
dependencies {
compile (project(':project-api-autoconfigure')) {
exclude module: 'project-module-a-api'
exclude module: 'project-module-b-api'
...
}
...
}
...
def loadProfile() {
def profile = hasProperty('profile') ? "${profile}" : "dev"
println "Profile: " + profile
apply from: "profiles/" + profile + ".gradle"
}
这或多或少。希望对你有所帮助。
干杯。