2018-03-09 Addendum Le même comportement a été obtenu lors de la mise à niveau vers Spring Boot 2.0.0.RELEASE.
20/12/2018 postscript Ajout de l'explication de Spring Boot 2.1.
Utilisez la classe FilterRegistrationBean
fournie par Spring Boot.
Lorsque vous définissez un FilterRegistrationBean
, le filtre est récupéré dans la classe de configuration automatique de Spring Boot et enregistré auprès du serveur intégré.
@Configuration
public class SomeConfig {
@Bean
public FilterRegistrationBean hogeFilter() {
//Nouveau filtre et transmettez-le au constructeur FilterRegistrationBean
FilterRegistrationBean bean = new FilterRegistrationBean(new HogeFilter());
//URL du filtre-Spécifiez le modèle (plusieurs spécifications peuvent être spécifiées car il s'agit d'un argument de longueur variable)
bean.addUrlPatterns("/*");
//Ordre d'exécution du filtre. Effectué pour viser des valeurs entières
bean.setOrder(Integer.MIN_VALUE);
return bean;
}
@Bean
public FilterRegistrationBean fugaFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean(new FugaFilter());
bean.addUrlPatterns("/*");
//Exécuté après HogeFilter
bean.setOrder(Integer.MIN_VALUE + 1);
return bean;
}
//N'importe quel nombre de filtres peut être défini
}
La méthode @ Bean
peut accepter d'autres beans comme arguments. C'est une fonctionnalité que Spring a à l'origine.
C'est OK si vous recevez le Bean reçu en argument avec le constructeur de Filter.
public class HogeFilter extends OncePerRequestFilter { //Bien sûr, "implements Filter" est également OK
private final FugaBean fugaBean; //Créer un champ
public HogeFilter(FugaBean fugaBean) { //Recevoir un bean dans le constructeur
this.fugaBean = fugaBean;
}
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
//Écrivez le prétraitement ici
chain.doFilter(request, response);
//Écrivez le post-traitement ici
}
}
@Configuration
public class HogeConfig {
@Bean
public FilterRegistrationBean hogeFilter(FugaBean fugaBean) {
//Passez le bean au constructeur Filter
FilterRegistrationBean bean = new FilterRegistrationBean(new HogeFilter(fugaBean));
// ...
return bean;
}
}
Le FugaBean doit être défini ailleurs (comme une autre classe Config ou une analyse de composant).
Notez que le filtre lui-même n'est pas un bean. Autrement dit, vous ne pouvez pas DI un bean vers un filtre avec
@ Autowired
ou appliquer un AOP à un filtre.
Il s'agit d'une classe appelée ServletContextInitializerBeans
qui récupère le filtre de FilterRegistrationBean
et l'enregistre auprès du serveur incorporé. C'est OK si vous sortez le journal DEBUG de cette classe (Remarque: journal TRACE après Spring Boot 2.1).
Le filtre est exécuté dans l'ordre croissant de la valeur de ʻorder`.
application.properties
# Boot 2.Après 1 est trace au lieu de débogage
logging.level.org.springframework.boot.web.servlet.ServletContextInitializerBeans=debug
Sortie standard
...
2018-02-28 11:58:37.611 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Filter initializer bean 'loggingFilter1'; order=-2147483648, resource=com.example.Application
2018-02-28 11:58:37.611 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Filter initializer bean 'loggingFilter2'; order=-2147483647, resource=com.example.Application
2018-02-28 11:58:37.612 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Filter initializer bean 'loggingFilter3'; order=-2147483646, resource=com.example.Application
2018-02-28 11:58:37.612 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Added existing Servlet initializer bean 'dispatcherServletRegistration'; order=2147483647, resource=class path resource [org/springframework/boot/autoconfigure/web/DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'characterEncodingFilter'; order=-2147483648, resource=class path resource [org/springframework/boot/autoconfigure/web/HttpEncodingAutoConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'hiddenHttpMethodFilter'; order=-10000, resource=class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'httpPutFormContentFilter'; order=-9900, resource=class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration.class]
2018-02-28 11:58:37.638 DEBUG 4323 --- [ost-startStop-1] o.s.b.w.s.ServletContextInitializerBeans : Created Filter initializer for bean 'requestContextFilter'; order=-105, resource=class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter.class]
...
Il est normal de définir le filtre lui-même comme un bean, mais je ne peux pas spécifier le modèle d'url ou l'ordre d'exécution. Il semble que même si vous spécifiez l'annotation @ Order
dans la méthode @ Bean
, elle sera ignorée (quelle que soit la valeur de @ Order
, la valeur de la sortie de la commande dans le journal sera 2147483647
).
@Bean
@Order(Integer.MIN_VALUE) //Cette valeur semble être ignorée (je ne sais pas s'il s'agit d'une spécification)
public HogeFilter hogeFilter() {
return new HogeFilter();
}
Alors utilisons FilterRegistrationBean
.
Spring Boot Reference https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-embedded-container-servlets-filters-listeners-beans Javadoc https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/web/servlet/FilterRegistrationBean.html