ฉันพบวิธีแก้ปัญหามาระยะหนึ่งแล้ว แต่ฉันลืมแบ่งปันที่นี่ ดังนั้นขอบคุณแจนที่เตือนฉัน
ฉันแก้ไขมันด้วยการสร้างและลงทะเบียนเซิร์ฟเล็ตของผู้ส่งหลายรายการด้วยบริบทแอปพลิเคชันเว็บใหม่ที่มีการกำหนดค่าที่แตกต่างกัน (RepositoryRestMvcConfiguration) และพาเรนต์ทั่วไปซึ่งเป็นบริบทแอปพลิเคชันรูทของแอปพลิเคชัน Spring Boot หากต้องการเปิดใช้งานโมดูล API โดยอัตโนมัติโดยขึ้นอยู่กับขวดที่แตกต่างกันที่รวมอยู่ใน classpath ฉันจำลองสิ่งที่ Spring Boot ทำได้ไม่มากก็น้อย
โปรเจ็กต์นี้แบ่งออกเป็นโมดูลการไล่ระดับหลายโมดูล บางสิ่งเช่นนี้:
- โครงการเซิร์ฟเวอร์
- โครงการ API-กำหนดค่าอัตโนมัติ
- โครงการโมดูล-a-api
- โครงการโมดูล-b-api
- ...
- โครงการโมดูล-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 เป็นที่ที่ฉันสร้าง servlet beans ของโปรแกรมเลือกจ่ายงานด้วยบริบทแอปพลิเคชันเว็บของตัวเองสำหรับโมดูล API ทุกโมดูล แต่การกำหนดค่านี้มีเงื่อนไขในคลาสการกำหนดค่าของโมดูล API ทุกโมดูลซึ่งอยู่ภายในแต่ละโมดูล API ไห.
ฉันสร้างและคลาสนามธรรมซึ่งคลาสการกำหนดค่าอัตโนมัติทุกอันสืบทอดมา:
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, โครงการโมดูล-b-api...
อาจเป็น RepositoryRestMvcConfiguration หรือสามารถขยายจากมัน หรืออาจเป็นคลาสการกำหนดค่าอื่น ๆ ที่นำเข้าการกำหนดค่า Spring Data REST
และสุดท้ายแต่ไม่ท้ายสุด ฉันสร้างสคริปต์ gradle ที่แตกต่างกันภายในโมดูลหลัก project-server ที่จะโหลดตามคุณสมบัติที่ส่งไปยัง 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"
}
และนั่นคือทั้งหมดไม่มากก็น้อย ฉันหวังว่ามันจะช่วยคุณได้ Jan.
ไชโย
person
Daniel Francisco Sabugal
schedule
13.02.2015