【问题标题】:Is there any way to inject Interceptor from external library in Spring?有什么方法可以在 Spring 中从外部库中注入拦截器?
【发布时间】:2022-02-08 08:59:24
【问题描述】:

我正在开发一个 jar 库并尝试将一个拦截器从外部 jar 库注入到应用程序。

例如:

外部库

MyExternalInterceptor.java

public class MyExternalInterceptor implements HandlerInterceptor {
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        // Do something
    }
}

我尝试在外部库中使用 AOP,但它不起作用。

InterceptorAspect.java

@Around("execution(* org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.addInterceptors(..))")
public Object aspect(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    // Tried to inject MyExternalInterceptor here
    Object result = proceedingJoinPoint.proceed();
    return result;
}

在使用该库的应用程序中:

应用

MyConfiguration.java

@Configuration
public MyConfiguration extends WebMvcConfigurationSupport {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SpringTestInterceptor()); // client's own interceptor
        /* Add MyExternalInterceptor not explicitly but implicitly using AOP or other things */
    }
}

有没有办法从外部库向 App 注入拦截器?

我知道这个问题非常晦涩(对此感到抱歉),但您能给我任何建议或提示以使其发挥作用吗?

感谢任何阅读我问题的人:)

(我更新了更多细节以进行澄清)

【问题讨论】:

  • 尝试将SpringTestInterceptor注释为@Component,并作为参数注入addInterceptors(...)
  • 只需添加一个带有@Configuration注解的WebMvcConfigurer不是 WebMvcConfigurerSupport!)即可注册您要注册的拦截器。您的图书馆的用户应该扫描/使用该配置类。您需要拨打addInterceptor 否则不会添加任何内容。
  • 嗨@AndrewS,感谢您的回答!实际上,我想注入 MyExternalInterceptor(而不是 SpringTestInterceptor)——抱歉让您感到困惑。
  • 真是一个惊喜!你拯救了我的一天@M.Deinum!这真的像魔术一样工作!我真的很感谢你:D

标签: java spring web aop interceptor


【解决方案1】:

总结

  • 在客户端和库端都使用WebMvcConfigurer 而不是WebMvcConfigurationSupport
  • 不需要 AoP

我使用 WebMvcConfigurer 而不是 WebMvcConfigurationSupport 并更改如下代码:

外部库

MyExternalInterceptor.java

  • 和以前一样

InterfaceAspect.java

  • 不再需要它了

MyExternalLibConfiguration.java

@Configuration
public class MyExternalLibConfiguration implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new MyExternalInterceptor());
    }
}

应用程序(客户端)

MyConfiguration.java

@Configuration
public MyConfiguration implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new SpringTestInterceptor()); // client's own interceptor
        /* No need to add MyExternalInterceptor in here */
    }
}

就是这样!正如M. Deinum 在评论中所说,一切都运行良好。

再次感谢 Deinum!

【讨论】:

  • Ehrm...你不需要所有这些。你**只有&&需要MyConfiguration...不需要AOP。只需将该配置包含在您的库中,它将自动使用(并删除应该是客户端应用程序的一部分而不是您的库代码的@EnableWebMvc)。如果在使用它的应用程序上禁用了 AspectJ 代理,则该方面甚至可能不会运行,您也不应该让您的库依赖于 aspectj...
  • 哦..我明白了。所以,你的意思是 - implements WebMvcConfigurer & 在库端的 Configuration.java 中实现 addInterceptors(..) - 只需在客户端的 Configuration.java 中更改为 WebMvcConfigurer 对吗?
  • 没有。对于你的库,包括一个实现WebMvcConfigurer 的类,用@Configuration 对其进行注释(尽管我怀疑@Component 也可以工作)并注册你的拦截器。该类将被客户端应用程序检测到,这将参与配置 Spring MVC 并因此注册拦截器。
  • 好的,那我写的答案是对的吗? (stackoverflow.com/a/71019792/7110084)
  • 如果你想让它更简单,并支持 Spring Boot,你也可以添加一个 spring.factories 类(如描述的here。那么对于 Spring Boot 唯一需要添加的是您的 jar,其他一切都将是自动的(不依赖于组件扫描来检测您的配置类)。
猜你喜欢
  • 2015-10-10
  • 1970-01-01
  • 1970-01-01
  • 2016-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-01
  • 1970-01-01
相关资源
最近更新 更多