【问题标题】:Spring boot and Jersey Filter with Dependency Injection带有依赖注入的 Spring Boot 和 Jersey 过滤器
【发布时间】:2019-11-17 11:41:14
【问题描述】:

有一个带有 Jersey 的 Spring Boot,我想使用一些内部使用依赖注入的过滤器。

问题是,Jersey Server 似乎无法使用 Spring 的 ApplicationContext,我们在其中定义了该依赖项。

这里是 JerseyConfiguration

@Configuration
public class JerseyConfig extends ResourceConfig {

    private static final String CONTEXT_CONFIG = "contextConfig";

    private static final String RESOURCE_PACKAGE = "presentation.resource";

    public JerseyConfig() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        applicationContext.refresh();
        property(CONTEXT_CONFIG, applicationContext);
        register(SpringLifecycleListener.class);
        register(MyFilter.class); //Filter I want to use 
        packages(RESOURCE_PACKAGE);
    }
}

这里是具有@Autowire 的过滤器

@Priority(40)
@Primary
@Provider
@MyFilter
class MyFilter(@Context var resourceInfo: ResourceInfo) extends ContainerRequestFilter with DefaultRuntime {

  implicit var finagleService: CommonFinagleService = _

  @Primary
  @Autowired(required = false)
  def setHttpFinagleService(@Autowired(required = false)
                            @Primary
                            _finagleService: CommonFinagleService): Unit = {
    finagleService = _finagleService
    finagleService.init(getProperties())
  }

  override def filter(context: ContainerRequestContext): Unit = {
    logger.debug(null, "filter running.....")
  }
}

这是applicationContext.xml的样子

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean id="httpFinagleService" class="foo.bla.CommonFinagleService"/>

</beans>

最后是Spring boot 主类

@Configuration
@SpringBootApplication(exclude = {org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration.class,
        org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration.class,
        org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.class,
        org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration.class})
public class SpringBootRestApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {

        new SpringBootRestApplication().configure(new SpringApplicationBuilder(SpringBootRestApplication.class)).run(args);
    }

我运行主类,调用 JerseyConfig 类,我可以注册过滤器。不幸的是,一旦服务运行,当我向一个端点运行请求时,过滤器被调用到 setHttpFinagleService 方法传递 CommonFinagleService 的空依赖项

我也在使用jersey-spring4 依赖

<dependency>
            <groupId>org.glassfish.jersey.ext</groupId>
            <artifactId>jersey-spring4</artifactId>
            <version>2.27</version>
        </dependency>

Spring boot 和 Spring 分别是 2.1.0 和 5.1.8

知道这里可能出了什么问题

Grizzly + Jersey 一切正常。

问候

【问题讨论】:

    标签: java spring spring-boot jersey jersey-2.0


    【解决方案1】:

    你需要将MyFilter设为Spring挑选的Bean,

    添加到类级别 @Component 并确保它被组件扫描拾取,如果有的话

    请注意,如果您使用 Spring DI,@Provider 可能是 redundant here

    【讨论】:

    • 但是我如何在 ResourceConfig 中注册?使用与 Grizzly + Jersey 相同的代码可以工作,并且 hk2 Dependecy Injection 是注入依赖项的一种。在这里,我认为问题在于 spring-boot-starter-jersey 没有正确执行 DI。无论如何,我会尝试按组件更改 Primary。
    • MyFilter 因为 Jersey 过滤器不能被 Spring boot DI 实例化,而是由 Jersey Spring + Hk2 实例化,因为它有一些 Spring 不知道如何实例化的内部依赖项。如果我尝试您提到的更改,我会收到错误:foo.bla 中构造函数的参数 0。 MyFilter 需要一个无法找到的“javax.ws.rs.container.ResourceInfo”类型的 bean。
    猜你喜欢
    • 1970-01-01
    • 2019-12-23
    • 2018-11-21
    • 1970-01-01
    • 2022-10-25
    • 1970-01-01
    • 2016-06-05
    • 2017-11-08
    • 1970-01-01
    相关资源
    最近更新 更多