I have spring boot application with some controllers.
All the controllers have @RequestMapping annotation with a path/value attribute. I would like to change the value of this attribute at runtime by hooking into the bean lifecycle.
I am using BeanPostProcessor.postProcessBeforeInitialization() to accomplish this and below is the reflection code that I use:
public class RequestMappingProcessor implements BeanPostProcessor
{
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
{
RequestMapping requestMapping = bean.getClass().getAnnotation(RequestMapping.class);
System.out.println("OldAnnotation Value " + requestMapping.value()[0]);
Map<String, Object> attributes = AnnotationUtils.getAnnotationAttributes(requestMapping);
String[] values = (String[]) attributes.get("path");
var newValue = getNewPath(path);
Object handler = Proxy.getInvocationHandler(annotation);
Field f;
try
{
f = handler.getClass().getDeclaredField("memberValues");
}
catch (NoSuchFieldException | SecurityException e)
{
throw new IllegalStateException(e);
}
f.setAccessible(true);
Map<String, Object> memberValues;
try
{
memberValues = (Map<String, Object>) f.get(handler);
}
catch (IllegalArgumentException | IllegalAccessException e)
{
throw new IllegalStateException(e);
}
Object oldValue = memberValues.get(key);
if (oldValue == null)
{
throw new IllegalArgumentException();
}
memberValues.put(key, newValue);
memberValues.put("path", newValue);
System.out.println("New Annotation Value " + requestMapping.value()[0]);
}
The things is that I do see it printing the updated values on console, but when I check the actual endpoint in postman or browser, still the old path works and not the new one. JDK 17.
I know that many would suggest to set the prefixed path at API level for all the controllers and all, but in my case, each controller might have a different prefix based upon some annotation. If you have some other suggestions, please suggest.
Aucun commentaire:
Enregistrer un commentaire