java 如何在spring mvc中修饰接口驱动控制器?

kfgdxczn  于 2023-09-29  发布在  Java
关注(0)|答案(2)|浏览(70)

我有一个像这样的接口驱动控制器:

@ResponseBody
@PreAuthorize("hasAnyRole('ADMIN', 'USER')")
@RequestMapping("/foo")
interface Foo {
    @GetMapping("/{id}")
    String bar(String id);
}

和委托给实际业务逻辑的实现

@Controller
public class FooImpl implements Foo {
    @Override
    public String bar(String id) {
        return "<actual business logic>";
    }
}

我想装饰接口Foo添加到应用程序的附加功能。
然而,当我使用jdk代理并尝试使用该spring启动应用程序时,它将不再注册端点。这是因为bean类型上不再使用@Controller进行注解。注解只存在于实现中(我不能使用@Bean方法,因为该注解只允许在类型上使用),而不是代理,现在spring web mvc看到的类型。我也不能用@Controller注解装饰和实现,因为那样我将有不明确的Map,因为装饰接口和实现将被视为需要为其创建处理程序Map的组件。
我还希望在实际业务逻辑的实现中保留控制器注解,以便控制器的主要焦点仍然很明显。
那么,我如何在spring web mvc中装饰一个接口驱动的控制器,同时保持实际的实现和任何应该应用到它的装饰是不同的呢?

ee7vknir

ee7vknir1#

我创建了一个额外的接口,用于将@Controller注解添加回已创建的代理:

@Controller
public interface AddControllerAnnotations {
}

我将这个接口附加地传递给用于创建代理示例的java.lang.reflect.Proxy.newProxyInstance(ClassLoader, Class<?>[], InvocationHandler)调用的接口。这样spring仍然会将装饰的示例视为控制器。
然而,如果将有更多注解以这种方式应用,则这将不会缩放。

tyu7yeag

tyu7yeag2#

在Spring Controller中使用代理需要基于类的代理,参考指南中甚至有一节解释了这一点,并对Spring Framework 6中的更改进行了额外的说明。
要在所有注解中强制启用类代理,您必须使用代理,如@EnableTransactionManagement@EnableAspectJAutoProxy等。

相关问题