I have a Servlet Filter within my Spring Boot (2.0.1) application that I'm registering with FilterRegistrationBean
which I need it to be executed first (order of one) along the filter chain. The application is deployed to JBoss 7.2 . This filter also has a dependency that is injected with @Autowired
(see below):
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
}
}
The problem is when the application is deployed and ran, when the Servlet request gets to MyFilter.doFilter()
, mySrv
is null which means MyFilter
was never scanned for dependency injections.
I can verify through debugging MyService
which is a @Repository
in my.package.com.repository
package does get initialized. It just never gets injected into MyFilter
.
I can create a constructor for MyFilter
to take MyService
, then @Autowired
MyService
into MyApp
and during filter registration, I can pass it to this constructor, which resolves the issue.
However, I want to know if there is anything I'm doing wrong that this dependency doesn't get injected into MyFilter
with using the setup above alone.
If you create an object by yourself, using new
, and this object is not returned by a @Bean
-annotated method, then it's not a Spring bean, and Spring will thus not inject anything in it.
You can just add an @Bean-annotated method returning new MyFilter()
, and call that method from myFilter()
to get the bean, or add a MyFilter
as argument to myFilter()
.
Example:
@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
}
or
@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
}
很简单,在过滤器类上添加@Component
批注,它将使@Autowired
批注在内部起作用,因为Spring依赖项注入将处理您的过滤器类并注入服务bean。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.