Dưới đây là một cách giải quyết, có thể có hoặc không có thể nguy hiểm.
Tạo lớp bên dưới "MyRequestMappingHandler", sau đó dây nó lên trong MvcConfig bạn
@Bean
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
return new MyRequestMappingHandler();
}
RequestMappingHandlerMapping: * NÀY KHÔNG PHẢI LÀ SẢN XUẤT MÃ - tùy thuộc vào bạn *
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.support.AopUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class MyRequestMappingHandler extends RequestMappingHandlerMapping {
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
RequestMappingInfo mappingForMethod = super.getMappingForMethod(method, handlerType);
// Check if this class extends a super. and that super is annotated with @Controller.
Class superClass = handlerType.getSuperclass();
if (superClass.isAnnotationPresent(Controller.class)) {
// We have a super class controller.
if (handlerType.isAnnotationPresent(Primary.class)) {
// We have a @Primary on the child.
return mappingForMethod;
}
} else {
// We do not have a super class, therefore we need to look for other implementations of this class.
Map<String, Object> controllerBeans = getApplicationContext().getBeansWithAnnotation(Controller.class);
List<Map.Entry<String, Object>> classesExtendingHandler = controllerBeans.entrySet().stream().filter(e ->
AopUtils.getTargetClass(e.getValue()).getSuperclass().getName().equalsIgnoreCase(handlerType
.getName()) &&
!AopUtils.getTargetClass(e.getValue()).getName().equalsIgnoreCase(handlerType.getName()))
.collect(Collectors.toList());
if (classesExtendingHandler == null || classesExtendingHandler.isEmpty()) {
// No classes extend this handler, therefore it is the only one.
return mappingForMethod;
} else {
// Classes extend this handler,
// If this handler is marked with @Primary and no others are then return info;
List<Map.Entry<String, Object>> classesWithPrimary = classesExtendingHandler
.stream()
.filter(e -> e.getValue().getClass().isAnnotationPresent(Primary.class) &&
!AopUtils.getTargetClass(e.getValue().getClass()).getName().equalsIgnoreCase
(handlerType.getName()))
.collect(Collectors.toList());
if (classesWithPrimary == null || classesWithPrimary.isEmpty()) {
// No classes are marked with primary.
return null;
} else {
// One or more classes are marked with @Primary,
if (classesWithPrimary.size() == 1 && AopUtils.getTargetClass(classesWithPrimary.get(0).getValue
()).getClass().getName().equalsIgnoreCase(handlerType.getName())) {
// We have only one and it is this one, return it.
return mappingForMethod;
} else if (classesWithPrimary.size() == 1 && !AopUtils.getTargetClass(classesWithPrimary.get(0)
.getValue()).getClass().getName().equalsIgnoreCase(handlerType.getName())) {
// Nothing.
} else {
// nothing.
}
}
}
}
// If it does, and it is marked with @Primary, then return info.
// else If it does not extend a super with @Controller and there are no children, then return info;
return null;
}
}
Điều này cho phép bạn làm là, mở rộng một lớp @Controller và đánh dấu nó bằng @Primary, và ghi đè lên một phương thức trên lớp đó, lớp mới của bạn bây giờ sẽ được nạp khi mùa xuân bắt đầu thay vì thổi lên với "nhiều bean/reques t ánh xạ vv"
Ví dụ về "siêu" Bộ điều khiển:
@Controller
public class Foobar {
@RequestMapping(method = "GET")
private String index() {
return "view";
}
}
Ví dụ về thực hiện:
@Primary
@Controller
public class MyFoobar extends Foobar {
@Override
private String index() {
return "myView";
}
}
Nguồn
2018-03-07 16:02:12
Không chắc liệu [' Order'] (http://docs.spring.io /spring-framework/docs/3.2.3.RELEASE/javadoc-api/org/springframework/core/annotation/Order.html) chú thích sẽ ảnh hưởng đến logic lập bản đồ xử lý (bạn có thể thử). Nếu không, bạn có thể ánh xạ tới một URL khác và triển khai một số loại viết lại (ví dụ: thông qua [URLRewriteFilter] (http://tuckey.org/urlrewrite/)). –
Phải sửa bản thân - 'Order' sẽ không hoạt động vì ánh xạ trùng lặp không được phép trong Spring (như Jordi đã chỉ ra trong câu trả lời của anh ấy). –