繁体   English   中英

通过反射更改注释值不起作用JDK17

[英]Changing Annotation value via Reflection does not work JDK17

我有带有一些控制器的 spring 引导应用程序。

所有控制器都有带有路径/值属性的@RequestMapping 注释。 我想通过挂钩到 bean 生命周期来在运行时更改此属性的值。

我正在使用 BeanPostProcessor.postProcessBeforeInitialization() 来完成此操作,下面是我使用的反射代码:

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]);
}

问题是我确实看到它在控制台上打印更新的值,但是当我在 postman 或浏览器中检查实际端点时,旧路径仍然有效,而不是新路径。 17.

我知道很多人会建议为所有控制器和所有控制器设置 API 级别的前缀路径,但在我的情况下,每个 controller 可能具有基于某些注释的不同前缀。 如果您有其他建议,请提出建议。

对于那些希望完成相同操作的人,您可以通过在自定义配置器中覆盖WebMvcConfigurer.configurePathMatch(PathMatchConfigurer configurer)方法并使用configurer.addPathPrefix()根据您的自定义逻辑为所有控制器设置前缀来实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM