我正在向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为null,这意味着从未对MyFilter进行依赖注入扫描。

我可以通过调试MyService进行验证,这是@Repository软件包中的my.package.com.repository确实被初始化了。它只是永远不会注入MyFilter中。

我可以为MyFilter创建一个构造器,以使MyService,然后将@Autowired MyService放入MyApp,并且在过滤器注册期间,可以将其传递给此构造器,从而解决了该问题。

但是,我想知道是否有我做错的事情,就是单独使用上述设置不会将此依赖项注入MyFilter中。

最佳答案

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

您可以只添加一个返回new MyFilter()的@Bean批注方法,然后从myFilter()调用该方法以获取bean,或者将MyFilter作为参数添加到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
}


要么

@Bean
@Order(1)
public FilterRegistrationBean<MyFilter> myFilter(MyFilter theActualFilter) {
    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
}

08-27 15:20