前提
順序"だけ"を制御したいときで、そのほかのことは一切やらない。
正攻法は参照先にもあるとおりFilterRegistrationBean
案1 Orderedを実装する。
以下の例の場合、本来は先に宣言されているfirstFilterのほうが先に作用するが、Orderdを実装することで、Orderdの順となる。
AppConfig.java
mport javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.filter.AbstractRequestLoggingFilter;
@Configuration
public class AppConfig {
/** ロガー */
private static final Logger log = LoggerFactory.getLogger(AppConfig.class);
@Bean("firstFilter")
public AbstractRequestLoggingFilter firstFilter() {
return new OrderdAbstractRequestLoggingFilter() {
@Override
protected void beforeRequest(HttpServletRequest request, String message) {
log.info("OrderdAbstractRequestLoggingFilter default first. order second");
}
@Override
protected void afterRequest(HttpServletRequest request, String message) {
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE + 1;
}
};
}
@Bean("secondFilter")
public AbstractRequestLoggingFilter secondFilter() {
return new OrderdAbstractRequestLoggingFilter() {
@Override
protected void beforeRequest(HttpServletRequest request, String message) {
log.info("OrderdAbstractRequestLoggingFilter default second. order first");
}
@Override
protected void afterRequest(HttpServletRequest request, String message) {
}
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE;
}
};
}
/**
* AbstractRequestLoggingFilterにOrderdインターフェースをくっつけただけのクラス
*/
private static abstract class OrderdAbstractRequestLoggingFilter extends AbstractRequestLoggingFilter implements Ordered {
}
}
仕組み
- org.springframework.boot.web.servlet.ServletContextInitializerBeans#getOrderedBeansOfTypeが順序決めに使用するのがorg.springframework.core.OrderComparator
- org.springframework.core.OrderComparatorはorg.springframework.core.Orderedを比較根拠として利用している。
案2 @ componentにする。
FirstFilter.java
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.AbstractRequestLoggingFilter;
@Component
@Order(1)
public class FirstFilter extends AbstractRequestLoggingFilter {
/** ロガー */
private static final Logger log = LoggerFactory.getLogger(FirstFilter.class);
@Override
protected void beforeRequest(HttpServletRequest request, String message) {
log.info("FirstFilter default first. order second");
}
@Override
protected void afterRequest(HttpServletRequest request, String message) {
}
}
SecondFilter.java
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.AbstractRequestLoggingFilter;
@Component
@Order(0)
public class SecondFilter extends AbstractRequestLoggingFilter {
/** ロガー */
private static final Logger log = LoggerFactory.getLogger(SecondFilter.class);
@Override
protected void beforeRequest(HttpServletRequest request, String message) {
log.info("SecondFilter default second. order first");
}
@Override
protected void afterRequest(HttpServletRequest request, String message) {
}
}
備考
なぜComponentであれば作用するのか仕組みは理解し切れていない。以下を見るとcomponentと記載があるので@Beanでは使えないケースもあるのかなと
@Order defines the sort order for an annotated component
~~~~~~~~~
参考先
https://qiita.com/suke_masa/items/7bdfab8e974931afdac5
https://www.baeldung.com/spring-boot-add-filter