Location>code7788 >text

Spring's three common interceptors explained

Popularity:491 ℃/2024-07-28 14:18:11

preamble

In the development process, we often use to interceptors to deal with some logic. The three most commonly used interceptors are AOP, Interceptor, Filter, but in fact, many people do not know when to use AOP, when to use Interceptor, when to use Filter, and do not know the order of its interception, internal principles. Today we introduce the three interceptors in detail.

interceptor order

We now have a controller interface called test, and now we have three interceptors defined in the project in the following order

Filter(before) > Interceptor(before) > AOP(before) > testmethodologies > AOP(after) > Interceptor(after) > Filter(after)

The exact process is shown in the two pictures below.

So sometimes we can't use AOP/Interceptor, we can only use Filter.

  • For example, if we have a Get request, but someone else sends a Post request, only a Filter can intercept it, so we can only use Filter.
  • Another example is that after we get the request parameters in the Interceptor, because it is a stream, the back of the controller will not be able to get, we will generally use the wrapper class to achieve repeated reading. But if we use AOP directly can avoid this problem.

There are more examples like this, so we should know what we are doing as well as what we are doing. Below we describe the specific usage of the three interceptors.

Filter Interceptor

The filter is the servlet level to provide interceptors, and spring has nothing to do. It is just that now spring/springboot reigns supreme, many projects in spring based on the use of filter. that if we use filter interceptor in spring project it

@Slf4j
public class FirstFilter implements Filter {
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

		("FirstFilter before doFilter");
		(servletRequest, servletResponse);
	}
}

@Slf4j
public class SecondFilter implements Filter {
	@Override
	public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

		("SecondFilter before doFilter");
		(servletRequest, servletResponse);
	}
}

@Slf4j
@Configuration
public class FilterConfig {

	@Bean
	public FilterRegistrationBean firstFilter() {
		FilterRegistrationBean registration = new FilterRegistrationBean();
		(new FirstFilter());
		("/*");
		("FirstFilter");
		// smaller the number,The higher the priority
		(1);
		return registration;
	}

	@Bean
	public FilterRegistrationBean secondFilter() {
		FilterRegistrationBean registration = new FilterRegistrationBean();
		(new SecondFilter());
		("/*");
		("SecondFilter");
		// larger the number,The lower the priority
		(2);
		return registration;
	}

}

output result

FirstFilter before doFilter

SecondFilter before doFilter

Interceptor

Interceptor is the interceptor provided to us by springmvc, which can only be used in sotingmvc

@Slf4j
@Component
public class FirstInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		("FirstInterceptor preHandle");
		return true;
	}
}

@Slf4j
@Component
public class SecondInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		("SecondInterceptor preHandle");
		return true;
	}

}

@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

	@Autowired
	private FirstInterceptor firstInterceptor;

	@Autowired
	private SecondInterceptor secondInterceptor;

	// Configuring Interception Rules
	public void addInterceptors(InterceptorRegistry registry) {

		// In order of registration,sequential implementation
		(firstInterceptor)
				.addPathPatterns("/**")
				.excludePathPatterns("/task/**");

		(secondInterceptor)
				.addPathPatterns("/**")
				.excludePathPatterns("/spring/**");
	}
}

output result

FirstInterceptor preHandle

SecondInterceptor preHandle

AOP interceptor

AOP is our very commonly used interceptor, weaving point, there are before, after, around, etc., we today to around for example

@Aspect
@Component
public class LoggerAOP {

	@Pointcut("execution (public * ..*(..))")
	public void pointcutLogger() {}

	@Around("pointcutLogger()")
	public Object methodAround(ProceedingJoinPoint joinPoint) throws Throwable {
		try {
			("request className = {}, method = {}, ip = {}, param = {}", className, methodName, ip, param);

			resp = ();

			long duration = ();
			("response className = {}, method = {}, resp = {}, cost = {}ms", className, methodName, buildResp(resp), duration);
		}

		catch (Throwable e) {
			("logger request className = {}, method = {} fail message = {} ",
					className, methodName, (), e);
			throw e;
		}
		return resp;
	}
}

ultimate

We went over the three interceptors that are commonly used in spring, and how they are used in springboot.

Finally give you a small homework, if you put the above three interceptors into a project, what order will he output?

[INFO  2024-07-27 16:01:52.146] [http-nio-8099-exec-2] [] - [:17] [FirstFilter before doFilter]
[INFO  2024-07-27 16:01:52.146] [http-nio-8099-exec-2] [] - [:17] [SecondFilter before doFilter]
[INFO  2024-07-27 16:01:52.148] [http-nio-8099-exec-2] [] - [:18] [FirstInterceptor preHandle]
[INFO  2024-07-27 16:01:52.148] [http-nio-8099-exec-2] [] - [:18] [SecondInterceptor preHandle]
[INFO  2024-07-27 16:01:52.148] [http-nio-8099-exec-2] [cdc644d0-afdf-4283-bf52-fc5fdd217746] - [:52] [request className = TestController, method = testController, ip = 0:0:0:0:0:0:0:1, param = [null]]

[INFO  2024-07-27 16:01:52.149] [http-nio-8099-exec-2] [cdc644d0-afdf-4283-bf52-fc5fdd217746] - [:57] [main process]

[INFO  2024-07-27 16:01:52.149] [http-nio-8099-exec-2] [cdc644d0-afdf-4283-bf52-fc5fdd217746] - [:62] [response className = TestController, method = testController, resp = "ok", cost = 0ms]