不仅可以拦截PostMapping 别的注解也可以
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author:pys
* @时间:2023年03月22日 14:14
* @说明:动态修改RequestMapping注解
*/
@Slf4j
@Component
public class RequestMappingPrefixBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
private static final String OLD_PREFIX = "/rest/rum";
private static final String NEW_PREFIX = "/api/rum";
private static final String VALUE = "value";
private static final String MEMBER_VALUES = "memberValues";
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
//获取RestController注解标注的bean
String[] beanNames = beanFactory.getBeanNamesForAnnotation(RestController.class);
for (String beanName : beanNames) {
//获取Class
Class<?> beanType = beanFactory.getType(beanName);
//如果被RequestMapping标注
if (beanType.isAnnotationPresent(RequestMapping.class)) {
//获取注解
RequestMapping annotation = beanType.getAnnotation(RequestMapping.class);
//获取RequestMapping的所有路径
String[] paths = annotation.value();
List<String> newPathList = new ArrayList<>();
//是否为 /rest/rum 开头的flag
boolean addedNewPrefixFlag = false;
String newPath = null;
//遍历url路径
for (String path : paths) {
if (path.startsWith(OLD_PREFIX)) {
log.info("old Annotation Value " + annotation.value()[0]);
newPath = path.replace(OLD_PREFIX, NEW_PREFIX);
//添加新的路径
newPathList.add(newPath);
addedNewPrefixFlag = true;
}
//添加老的路径
newPathList.add(path);
break;
}
//如果添加成功
if (addedNewPrefixFlag && newPath != null) {
//调转顺序 framework识别的是 path[0]的路径 所以要把/api/rum放前边 /rest/rum放后边
newPathList.add(0, newPath);
String[] newPaths = newPathList.toArray(new String[0]);
Field f;
try {
//获取代理handler
Object handler = Proxy.getInvocationHandler(annotation);
//获取RequestMapping真正属性存值的地方
f = handler.getClass().getDeclaredField(MEMBER_VALUES);
f.setAccessible(true);
Map<String, Object> memberValues;
memberValues = (Map<String, Object>) f.get(handler);
//替换value
memberValues.put(VALUE, newPaths);
log.info("New Annotation Value " + annotation.value()[0]);
} catch (Exception e) {
log.error("Failed to set annotation value: " + e.getMessage(), e);
}
}
}
}
}
}