Tôi đã trải nghiệm một số Spring ngay bây giờ và cũng có một số ứng dụng web cấu hình java thuần túy đang được sử dụng. Tuy nhiên, đây là những thường dựa trên một thiết lập đơn giản yên tĩnh:Cấu hình Spring Java với nhiều Dispatchers
- ứng dụng cấu hình cho các dịch vụ/kho
- cấu hình điều phối cho một điều phối (và một số bộ điều khiển) an ninh
- (không bắt buộc) vào mùa xuân để bảo đảm khả năng tiếp cận
Đối với dự án hiện tại của tôi, tôi cần có bối cảnh điều phối riêng biệt với cấu hình khác. Đó không phải là vấn đề với cấu hình dựa trên XML vì chúng ta có một ContextLoaderListener chuyên dụng độc lập với Cấu hình Dispatcher. Nhưng với java cấu hình Tôi không chắc chắn nếu những gì tôi đang làm là tốt cho đến nay;)
Dưới đây là một DispatcherConfig chung:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new class[]{MyAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{MyDispatcherConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/mymapping/*"};
}
@Override
protected String getServletName() {
return "myservlet";
}
}
Như đã nói, tôi cần một thứ hai (thứ ba, ...) điều phối với một ánh xạ khác (và xem các giải pháp). Vì vậy, tôi đã sao chép cấu hình và được thêm vào cho cả hai getServletName() (nếu không cả hai sẽ được đặt tên là 'điều phối' sẽ gây ra lỗi). Các cấu hình thứ hai được tìm như thế:
public class AnotherWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new class[]{MyAppConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{AnotherDispatcherConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/another_mapping/*"};
}
@Override
protected String getServletName() {
return "anotherservlet";
}
}
Khi tôi sử dụng nó như thế này, bắt đầu từ kết quả ứng dụng trong một vấn đề với ContextLoaderListener:
java.lang.IllegalStateException: Cannot initialize context because there is already a root application context present - check whether you have multiple ContextLoader* definitions in your web.xml!
at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:277)
...
Vì vậy, tôi loại bỏ các MyAppConfig.class thứ hai trở về từ một trong số AbstractAnnotationConfigDispatcherServletInitializer và hoạt động tốt. Tuy nhiên, điều đó không cảm thấy đúng cách;)
Vì sự hiểu biết của tôi: tất cả nên DispatcherConfig được xử lý trong một AbstractAnnotationConfigDispatcherServletInitializer hoặc tôi nên tách chúng như tôi đã làm? Tôi đã cố gắng để cấu hình chúng trong một lớp nhưng sau đó cấu hình của tôi đã hoàn toàn hỗn hợp (vì vậy tôi tin rằng đó không phải là cách mong muốn).
Làm cách nào để bạn triển khai trường hợp như vậy? Có thể đặt ContextLoaderListener trong cấu hình java bên ngoài AbstractAnnotationConfigDispatcherServletInitializer không? Hoặc tôi có nên tạo một DefaultServlet chỉ có cấu hình gốc không? Điều gì về việc triển khai giao diện cơ sở của cấu hình đó WebApplicationInitializer?
Bạn có thể giải thích lý do cần nhiều điều vận trong một ứng dụng duy nhất? Toàn bộ điểm của Front Controller là bạn ghép các yêu cầu của bạn lên một. – chrylis
@chrylis: chắc chắn. Dự án này giống như một bộ xây dựng dựa trên mô-đun cho các dịch vụ dùng chung. Đây không phải là liên kết với nhau nhưng chia sẻ cùng một cơ sở thiết lập và các thực thể. Có hai ứng dụng để triển khai là không có trong dự án đó và cố gắng định cấu hình trình điều phối để xử lý tất cả các loại công nghệ xem (một số dựa trên gạch, các ứng dụng khác trên jsp, những cái mới hơn trên Thymeleaf) cũng là một ý tưởng tồi. – delimiter
Tại sao lại là một ý tưởng tồi? Spring Boot giúp bạn dễ dàng. – chrylis