如何在Spring Boot中注册具有构造函数依赖关系的HandlerInterceptor



我的用例是通过注释方法在控制器方法之前运行自定义代码。

HandlerInterceptor似乎是可行的,但似乎不可能将依赖项注入其中,因为它需要在创建上下文之前进行注册。

到目前为止,我发现的所有示例都在配置中使用了空构造函数(请参阅spring-boot添加http请求拦截器(或autowire属性,但由于我在同一配置中声明了依赖bean(请求的bean当前正在创建中:是否存在无法解决的循环引用?(,因此失败。

有没有更好的方法不涉及AOP?

假设您的拦截器具有如下构造函数依赖项:

public class CustomInterceptor extends HandlerInterceptor {
private final DependentBean bean;
public CustomInterceptor(DependentBean bean) {
this.bean = bean;
}
}

然后你可以这样注册你的处理程序:

@Configuration
public WebConfig extends WebMvcConfigurerAdapater {
@Bean
public DependentBean dependentBean() {
return new DependentBean();
}

@Bean
public CustomInterceptor customInterceptor() {
return new CustomInterceptor(dependentBean());
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor());
}
}

@Configuration将确保每个Bean方法调用返回相同的bean实例

基于M的上述答案ạnh,如果使用组件扫描来注入依赖项,则可以在WebConfig 中自动连线

@Configuration
public WebConfig extends WebMvcConfigurerAdapater {
@Autowired
DependentBean dependentBean;
@Bean
public CustomInterceptor customInterceptor() {
return new CustomInterceptor(dependentBean);
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(customInterceptor());
}
}

还基于以前的答案,如果您使用Lombok,您可以进一步简化。

  1. 您的拦截器实现是@Component

  2. 添加一个private final DependentBean字段。

  3. 还添加了一个@RequiredArgsConstructor注释,让Lombok生成一个带有单个DependentBean参数的构造函数。

  4. 在您的WebConfig中,使用相同的技术由Spring IOC注入private final CustomInterceptor字段。

这样,CustomInterceptor实例将可用&当addInterceptors将被称为时,以正确的方式初始化


以下是相应的代码示例:


CustomInterceptor:
@Component
@RequiredArgsConstructor
public class CustomInterceptor implements HandlerInterceptor {
private final DependentBean dependentBean;
@Override
public boolean preHandle( final HttpServletRequest request,
final HttpServletResponse response,
final Object handler ) throws Exception {
// your Interceptor Implementation goes here ...
}
}
WebConfig:
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final CustomInterceptor customInterceptor;
@Override
public void addInterceptors( final InterceptorRegistry registry ) {
registry.addInterceptor( customInterceptor );
}
}

最新更新