如何使用Spring Boot过滤器注册Bean将依赖项注入Servlet过滤器?

时间:2019-08-16 20:01:42

标签: java spring spring-boot servlet-filters

我在向FilterRegistrationBean注册的Spring Boot(2.0.1)应用程序中有一个Servlet过滤器,我需要它首先沿着过滤器链执行(一个顺序)。该应用程序已部署到 JBoss 7.2 。此过滤器还具有@Autowired注入的依赖项(请参见下文):

package my.pkg.com
@SpringBootApplication
@ComponentScan(basePackages={"my.pkg.com"})
public class MyApp extends SpringBootServletInitializer {
  public satic void main(String[] args) throws IOException {
    SpringApplication.run(MyApp.class, args);
  }

  @Bean
  @Order(1)
  public FilterRegistrationBean<MyFilter> myFilter() {
    FilterRegistrationBean<MyFilter> contextFilter = new FilterRegistrationBean<>();
    contextFilter.setFilter(new MyFilter());
    contextFilter.addUrlPattern("/api/*");
    return contextFilter;
  }
}


package my.pkg.com.filter

public class MyFilter extends Filter {

  @Autowired
  private MyService mySrv;


  @Override

  public void doFilter(…) {

    mySrv.doSomething(); // mySrv is null
  }
}

问题在于,当部署和运行应用程序时,当Servlet请求到达MyFilter.doFilter()时,mySrv为空,这意味着从未对MyFilter进行依赖注入扫描。

我可以通过调试MyService来验证,@Repositorymy.package.com.repository包中的MyFilter确实已初始化。它只是永远不会注入MyFilter

我可以为MyService创建一个构造函数,以容纳@Autowired,然后将MyService MyApp放入MyFilter,并在过滤器注册期间将其传递给构造函数,可以解决问题。

但是,我想知道我是否做错了什么,仅使用上述设置不会将此依赖项注入=中。

2 个答案:

答案 0 :(得分:1)

如果您使用new自己创建了一个对象,并且该对象不是由带注释的@Bean返回的,则它不是Spring Bean,因此Spring不会在其中注入任何内容它。

您可以只添加一个返回new MyFilter()的@Bean注释方法,并从myFilter()调用该方法以获取bean,或者将MyFilter作为参数添加到{{1} }。

示例:

myFilter()

@Bean
@Order(1)
public FilterRegistrationBean<MyFilter> myFilter() {
    FilterRegistrationBean<MyFilter> contextFilter = new FilterRegistrationBean<>();
    contextFilter.setFilter(theActualFilter());
    contextFilter.addUrlPattern("/api/*");
    return contextFilter;
}

@Bean 
public MyFilter theActualFilter() {
    return new MyFilter(); // now this is a Spring bean
}

答案 1 :(得分:0)

很简单,在过滤器类上添加@Component批注,它将使@Autowired批注在内部起作用,因为Spring依赖项注入将处理您的过滤器类并注入服务bean。

相关问题