当前位置:网站首页>Interpretation of filter execution sequence source code in sprigboot
Interpretation of filter execution sequence source code in sprigboot
2022-07-25 20:28:00 【Firewood boy】
Preface
This article is mainly to clarify the same request in springboot Custom in the project filter and jar In bag filter How to specify the execution order of .
1. The request arrives at custom controller What filters have been used in the method before ?
Start with the request , Consider requesting customization when it arrives controller What filters have you entered before .
Go straight to the point , All requests for access will pass through filters , When the method returns, it will be executed from the back to the front in the order of the filter , The technical term is called filter chain , like , You climb from the first floor to the fifth floor , It must be from the fifth floor to the first floor , So is the request . Request sent , An important method involving filter execution is ApplicationFilterChain.java in internalDoFilter, It defines the execution order of the filter
private void internalDoFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
// pos Indicates the number of current requests that have passed the filter chain ;n Indicates the total number of filter chains ,this.filters Contains the filter array that the request needs to pass ,ApplicationFilterConfig It can be understood as the configuration class corresponding to the filter .
if (this.pos < this.n) {
ApplicationFilterConfig filterConfig = this.filters[this.pos++];
try {
Filter filter = filterConfig.getFilter();
if (request.isAsyncSupported() && "false".equalsIgnoreCase(filterConfig.getFilterDef().getAsyncSupported())) {
request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", Boolean.FALSE);
}
if (Globals.IS_SECURITY_ENABLED) {
Principal principal = ((HttpServletRequest)request).getUserPrincipal();
Object[] args = new Object[]{
request, response, this};
SecurityUtil.doAsPrivilege("doFilter", filter, classType, args, principal);
} else {
// Implement the self implemented in the filter doFilter Logic
filter.doFilter(request, response, this);
}
}
// Omit some irrelevant codes
}
} else {
try {
// Omit some irrelevant codes
// perform severlet Specific service implementation logic
this.servlet.service(request, response);
// Omit some irrelevant codes
} finally {
if (ApplicationDispatcher.WRAP_SAME_OBJECT) {
lastServicedRequest.set((Object)null);
lastServicedResponse.set((Object)null);
}
}
}
}
So you can see from the above that the request is sent , Is in accordance with the ApplicationFilterChain.java in filters The array is executed in sequence . Let's take a look at the inside filters How to initialize arrays when initializing items .
2. How to set the filter loading order during project startup
During the start of the project :ServletContextInitializerBeans.java in getOrderedBeansOfType Used to get the specified type bean aggregate . Among them the filter Type of bean In the collection processing, the execution order of the filter is set .
private <T> List<Entry<String, T>> getOrderedBeansOfType(ListableBeanFactory beanFactory, Class<T> type,
Set<?> excludes) {
// Get all interface javax.servlet.Filter Type of bean name .
String[] names = beanFactory.getBeanNamesForType(type, true, false);
Map<String, T> map = new LinkedHashMap<>();
for (String name : names) {
if (!excludes.contains(name) && !ScopedProxyUtils.isScopedTarget(name)) {
T bean = beanFactory.getBean(name, type);
if (!excludes.contains(bean)) {
map.put(name, bean);
}
}
}
List<Entry<String, T>> beans = new ArrayList<>(map.entrySet());
// Will all filter dependent bean according to order Compare size sort ,order The smaller the value, the more forward .
beans.sort((o1, o2) -> AnnotationAwareOrderComparator.INSTANCE.compare(o1.getValue(), o2.getValue()));
return beans;
}
Take the current project as an example , The project is started without sorting filter order :
The order after the order :
Continue to dig deep below beans.sort Filter sorting logic in
beans.sort((o1, o2) -> AnnotationAwareOrderComparator.INSTANCE.compare(o1.getValue(), o2.getValue()));
The main logic implemented is actually to get the of each filter order value , Then compare them separately . The logic is as follows :
private int doCompare(@Nullable Object o1, @Nullable Object o2, @Nullable OrderComparator.OrderSourceProvider sourceProvider) {
// Omitted code
int i1 = this.getOrder(o1, sourceProvider);
int i2 = this.getOrder(o2, sourceProvider);
return Integer.compare(i1, i2);
}
obtain order The value method is :OrderComparator.java in getOrder, Among them through findOrder Get specific order value , If not, the default order value :Ordered.LOWEST_PRECEDENCE, It is the final execution .
protected int getOrder(@Nullable Object obj) {
if (obj != null) {
Integer order = findOrder(obj);
if (order != null) {
return order;
}
}
// If there is no annotation in the filter or there is no order attribute , Will give a default value , This default value indicates the last execution
return Ordered.LOWEST_PRECEDENCE;
}
OrderComparator.java in findOrder There are two ways to do it , One is OrderComparator.java in findOrder, It's actually getting filter Custom member variables in order value .
protected Integer findOrder(Object obj) {
return (obj instanceof Ordered ? ((Ordered) obj).getOrder() : null);
}
for instance OrderedRequestContextFilter.java in , Is defined by member variables order value .
public class OrderedRequestContextFilter extends RequestContextFilter implements OrderedFilter {
private int order = -105;
public OrderedRequestContextFilter() {
}
public int getOrder() {
return this.order;
}
public void setOrder(int order) {
this.order = order;
}
}
Another way is AnnotationAwareOrderComparator.java in findOrderFromAnnotation, The main execution logic method name of the method has been clearly stated : from @Order In order to get order value , No more explanation here . For example, custom filters pass @Order Note to specify order value .
@Component
@Slf4j
@Order(Integer.MIN_VALUE)
public class RequestDetailFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("RequestDetailFilter init");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// Omit business implementation
}
@Override
public void destroy() {
log.info("RequestDetailFilter destroy");
}
}
summary : During the start of the project , load bean Into the container , Will filter type bean Object according to order Value size for sorting . Methods are executed in order filter To perform .
The filter execution sequence analysis in this request has been sorted out , If you feel fruitful, please leave a message or like in the comment area !
边栏推荐
- Cloud native, Intel arch and cloud native secret computing three sig online sharing! See you today | issues 32-34
- DIY个人服务器(diy存储服务器)
- Do you still have certificates to participate in the open source community?
- 【云原生 | 从零开始学Kubernetes】八、命名空间资源配额以及标签
- Aircraft PID control (rotor flight control)
- 参与开源社区还有证书拿?
- 什么是聚类分析?聚类分析方法的类别[通俗易懂]
- 2022.7.24-----leetcode.1184
- Rainbow plug-in extension: monitor MySQL based on MySQL exporter
- Chinese son-in-law OTA Ono became the first Asian president of the University of Michigan, with an annual salary of more than 6.5 million!
猜你喜欢

Docker 搭建 Redis Cluster集群

【高等数学】【4】不定积分

火山引擎项亮:机器学习与智能推荐平台多云部署解决方案正式发布

Cloud native, Intel arch and cloud native secret computing three sig online sharing! See you today | issues 32-34

4everland storage node portal network design

Rainbow plug-in extension: monitor MySQL based on MySQL exporter

【ONNX】pytorch模型导出成ONNX格式:支持多参数与动态输入

Difference Between Accuracy and Precision

毕业从事弱电3个月,我为什么会选择转行网络工程师

推荐系统专题 | MiNet:跨域CTR预测
随机推荐
103. (cesium chapter) cesium honeycomb diagram (square)
[today in history] July 15: Mozilla foundation was officially established; The first operation of Enigma cipher machine; Nintendo launches FC game console
qml 结合 QSqlTableModel 动态加载数据 MVC「建议收藏」
Volcanic engine Xiang Liang: machine learning and intelligent recommendation platform multi cloud deployment solution officially released
「分享」DevExpress ASP.NET v22.1最新版本系统环境配置要求
[advanced mathematics] [3] Application of differential mean value theorem and derivative
Mobile web layout method
Proxy实现mysql读写分离
【ONNX】pytorch模型导出成ONNX格式:支持多参数与动态输入
[today in history] July 13: the father of database passed away; Apple buys cups code; IBM chip Alliance
Apache MINA框架「建议收藏」
CarSim仿真快速入门(十五)—CarSim传感器仿真之ADAS Sensor Objects (1)
【NOI模拟赛】字符串匹配(后缀自动机SAM,莫队,分块)
Fanoutexchange switch code tutorial
Technology cloud report: what is the difference between zero trust and SASE? The answer is not really important
Notes - record a cannotfinddatasourceexception: dynamic datasource can not find primary datasource problem solving
[tensorrt] trtexec tool to engine
4、Nacos 配置中心源码解析之 服务端启动
CarSim仿真快速入门(十四)—CarSim-Simulink联合仿真
Recommended system topic | Minet: cross domain CTR prediction