SpringBoot使用过滤器、拦截器、切面(AOP),及其之间的区别和执行顺序
SpringBoot使⽤过滤器、拦截器、切⾯(AOP),及其之间的区别和执
⾏顺序
先上代码,下⾯的demo中包含多个拦截器、过滤器,以及切⾯的前置通知/后置通知/环绕通知:
下⾯总结⼀下相关原理:
⾸先了解⼀下SpringMVC的执⾏流程
具体流程如下
1. ⽤户发起请求到前端控制器(Controller)
2. 前端控制器没有处理业务逻辑的能⼒,需要找到具体的模型对象处理(Handler),到处理器映射器(HandlerMapping)中查找Handler对象(Model)。
3. HandlerMapping返回执⾏链,包含了2部分内容: ① Handler对象、② 拦截器数组
4. 前端处理器通过处理器适配器包装后执⾏Handler对象。
5. 处理业务逻辑。
6. Handler处理完业务逻辑,返回ModelAndView对象,其中view是视图名称,不是真正的视图对象。
7. 将ModelAndView返回给前端控制器。8. 视图解析器(ViewResolver)返回真正的视图对象(View)。
9. (此时前端控制器中既有视图⼜有Model对象数据)前端控制器根据模型数据和视图对象,进⾏视图渲染。
10. 返回渲染后的视图(html/json/xml)返回。
11. 给⽤户产⽣响应。
核⼼就是DispatcherServlet核⼼控制器,我们看源码可知道DispatcherServlet是Servlet的⼦类
下⾯⽤⼀张图说⼀下过滤器、Servlet容器、拦截器、AOP、Controller之间的关系
然后具体执⾏流程如下:
拦截器和过滤器的区别
1、拦截器不依赖与servlet容器是SpringMVC⾃带的,过滤器依赖于Servlet容器。
2、拦截器是基于java的反射机制的,⽽过滤器是基于函数回调。
3、拦截器只能对action请求起作⽤,⽽过滤器则可以对⼏乎所有的请求起作⽤。
4、拦截器可以访问controller上下⽂、值栈⾥的对象,⽽过滤器不能访问。
(拦截器的preHandle⽅法在进⼊controller前执⾏,⽽拦截器的postHandle⽅法在执⾏完controller业务流程后,在视图解析器解析ModelAndView之前执⾏,可以操控Controller的
ModelAndView内容。⽽afterCompletion是在视图解析器解析渲染ModelAndView完成之后执⾏的)
( 过滤器是在服务器启动时就会创建的,只会创建⼀个实例,常驻内存,也就是说服务器⼀启动就会执⾏Filter的init(FilterConfig config)⽅法.当Filter被移除或服务器正常关闭时,
会执⾏destroy⽅法)
5、拦截器可以获取IOC容器中的各个bean,⽽过滤器就不⾏,这点很重要,在拦截器⾥注⼊⼀个service,可以调⽤业务逻辑。
(关于这句话的解读是:我们知道拦截器是SprinMVC⾃带的,⽽SpringMVC存在Controller层的,⽽controller层可以访问到service层,service层是不能访问service层的,⽽过滤器
是客户端和服务端之间请求与响应的过滤)
6、过滤器和拦截器触发时机、时间、地⽅不⼀样
(过滤器是在请求进⼊容器后,但请求进⼊servlet之前进⾏预处理的。请求结束返回也是在servlet处理完后,返回给前端之前,如果看不懂可以看7完后再来理解)
7、过滤器包裹住servlet,servlet包裹住拦截器。
SpringBoot使用过滤器、拦截器、切面(AOP),及其之间的区别和执行顺序
SpringBoot使⽤过滤器、拦截器、切⾯(AOP),及其之间的区别和执
⾏顺序
先上代码,下⾯的demo中包含多个拦截器、过滤器,以及切⾯的前置通知/后置通知/环绕通知:
下⾯总结⼀下相关原理:
⾸先了解⼀下SpringMVC的执⾏流程
具体流程如下
1. ⽤户发起请求到前端控制器(Controller)
2. 前端控制器没有处理业务逻辑的能⼒,需要找到具体的模型对象处理(Handler),到处理器映射器(HandlerMapping)中查找Handler对象(Model)。
3. HandlerMapping返回执⾏链,包含了2部分内容: ① Handler对象、② 拦截器数组
4. 前端处理器通过处理器适配器包装后执⾏Handler对象。
5. 处理业务逻辑。
6. Handler处理完业务逻辑,返回ModelAndView对象,其中view是视图名称,不是真正的视图对象。
7. 将ModelAndView返回给前端控制器。8. 视图解析器(ViewResolver)返回真正的视图对象(View)。
9. (此时前端控制器中既有视图⼜有Model对象数据)前端控制器根据模型数据和视图对象,进⾏视图渲染。
10. 返回渲染后的视图(html/json/xml)返回。
11. 给⽤户产⽣响应。
核⼼就是DispatcherServlet核⼼控制器,我们看源码可知道DispatcherServlet是Servlet的⼦类
下⾯⽤⼀张图说⼀下过滤器、Servlet容器、拦截器、AOP、Controller之间的关系
然后具体执⾏流程如下:
拦截器和过滤器的区别
1、拦截器不依赖与servlet容器是SpringMVC⾃带的,过滤器依赖于Servlet容器。
2、拦截器是基于java的反射机制的,⽽过滤器是基于函数回调。
3、拦截器只能对action请求起作⽤,⽽过滤器则可以对⼏乎所有的请求起作⽤。
4、拦截器可以访问controller上下⽂、值栈⾥的对象,⽽过滤器不能访问。
SpringBoot中filter的使用详解及原理
SpringBoot中filter的使用详解及原理
Spring Boot是基于Spring Framework的快速开发框架,它通过自动配置,简化了Spring的配置过程。在Spring Boot中使用filter,可以方便地实现对请求和响应的过滤和处理。本文将详细介绍Spring Boot中filter的使用方法和原理。
一、使用filter的步骤
1. 创建一个实现javax.servlet.Filter接口的类,实现其doFilter方法。
2. 在该类上使用javax.servlet.annotation.WebFilter注解标明该类是一个filter,并指定其拦截的URL模式。
二、filter的原理
在Spring Boot中,使用filter的原理是通过Servlet容器来实现的。当一个请求到达Servlet容器时,Servlet容器会根据配置的过滤器链依次将请求转发给各个filter进行处理,最终再将请求传递给目标Servlet或者Controller处理。处理完请求后,再按照相反的顺序将响应返回给客户端。
三、filter的执行顺序
在Spring Boot中,filter的执行顺序是根据filter的声明顺序决定的。在WebMvcConfigurer中,可以通过addFilter方法将filter添加到过滤器链中,并且可以根据需要设置filter的顺序。如果没有配置filter的顺序,默认按照filter类的名称的字母顺序执行。
四、示例代码 下面我们以一个简单的登录认证的filter为例,来演示filter的使用方法和原理。
1. 创建LoginFilter类,实现javax.servlet.Filter接口,并重写doFilter方法。
```
public class LoginFilter implements Filter
public void doFilter(ServletRequest request, ServletResponse
Spring AOP 拦截器顺序
Spring AOP 拦截
在Spring 的AOP中,如果一个Proxy同时实现MethodBeforeAdvice、AfterReturningAdvice和MethodInterceptor接口,那么这三个Advice的执行顺序是什么样的呢?
经过试验,是和xml文件中的定义顺序有关的。
如果Proxy的接口实现定义为
MethodBeforeAdvice
AfterReturningAdvice
MethodInterceptor
那么执行的结果是
MethodBeforeAdvice
MethodInterceptor: before call
Really method excuting
MethodInterceptor: after call
AfterReturningAdvice
也就是说,执行顺序是:MethodBeforeAdvice,MethodInterceptor的调用前的部分,目标方法,MethodInterceptor的调用后的部分,AfterReturningAdvice。
如果proxy的定义是
MethodBeforeAdvice
MethodInterceptor
AfterReturningAdvice
执行的结果是
MethodBeforeAdvice
MethodInterceptor: before call
Really method excuting
AfterReturningAdvice
MethodInterceptor: after call
也就是说,执行的顺序是:MethodBeforeAdvice,MethodInterceptor的调用前的部分,目标方法,AfterReturningAdvice,MethodInterceptor的调用后的部分。
springboot使用之多个filter的执行顺序以及配置方式
springboot使⽤之多个filter的执⾏顺序以及配置⽅式
springboot 多个filter的执⾏顺序以及配置
当项⽬中有多个filter时,为了便于管理,可以创建⼀个配置⽂件,对所有的filter进⾏管理。
有的⽅法可能同时需要多个filter依次对其进⾏过滤,这时候便需要对filter的执⾏进⾏优先级的排序。如下:
新建⼀个配置⽂件ComponentFilterOrderConfig.java
先⽣成⼀个过滤器的bean,再把过滤器的bean注⼊到FilterRegistrationBean中,并设置⼀些属性,过滤的url,执⾏的顺序之
类的(order的数值越⼩,优先级越⾼)即可。
在MyHiddenHttpMethodFilter.java和TokenAuthorFilter.java⾥⾯不需要在添加注解@WebFilter(urlPatterns={})或
@Configuration @Component等注解
@Configuration
public class ComponentFilterOrderConfig {
@Bean
public Filter MyHiddenHttpMethodFilter(){
return new MyHiddenHttpMethodFilter();//⾃定义的过滤器
}
@Bean
public Filter tokenAuthorFilter(){
return new TokenAuthorFilter();//⾃定义的过滤器
}
@Bean
public FilterRegistrationBean filterRegistrationBean1(){
FilterRegistrationBean filterRegistrationBean=new FilterRegistrationBean();
filterRegistrationBean.setFilter(MyHiddenHttpMethodFilter());
SpringBoot自定义过滤器的两种方式及过滤器执行顺序
SpringBoot⾃定义过滤器的两种⽅式及过滤器执⾏顺序
第⼀种 @WebFilter + @ServletComponentScan 注解
1、⾸先⾃定义过滤器
如下⾃定义过滤器 ReqResFilter 必须实现 javax.servlet.Filter。
然后添加注解 @WebFilter(javax.servlet.annotation.WebFilter),urlPatterns 过滤器要过滤的URL规则配置,filterName 过滤器的名称。
@Order(int) 注解,配合 @WebFilter 注解使⽤,⽤于多个过滤器时定义执⾏顺序,值越⼩越先执⾏。
记住上⾯这句话,稍后再说。
package com.wenbei.filter;
import lombok.extern.slf4j.Slf4j;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
//@Order(1)
@Slf4j
@WebFilter(urlPatterns = "/*", filterName = "reqResFilter")
public class ReqResFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
Spring AOP原理及拦截器
原理
AOP(AspectOrientedProgramming),也就是面向方面编程的技术。AOP基于IoC基础,是对OOP的有益补充。
AOP将应用系统分为两部分,核心业务逻辑(Corebusinessconcerns)及横向的通用逻辑,也就是所谓的方面Crosscuttingenterpriseconcerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(TransactionManagement)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。
AOP正在成为软件开发的下一个光环。使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。
Springframework是很有前途的AOP技术。作为一种非侵略性的、轻型的AOPframework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOPframework,其他人还是像往常一样编程。
AOP概念
让我们从定义一些重要的AOP概念开始。
—方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。
—连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。 —通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。
—切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。
springbootgateway过滤器的执行顺序
springbootgateway过滤器的执⾏顺序
前⾔学习官⽅⽂档,发现对于过滤器有分为三类默认过滤器⾃定义过滤
全局过滤器
于是就有⼀个疑问,关于这些过滤器的访问顺序是怎样的,今天就以⼀个demo来进⾏测试
准备阶段
过滤器⼯⼚类
以此为模板,复制出⼏份就可以了,注意打印信息,可区分就⾏
public class ExampleGatewayFilterFactory extends AbstractGatewayFilterFactory {
/**
* 创造出的过滤器的顺序
*/
private int order;
/**
* constructor
*/
public ExampleGatewayFilterFactory(int order) {
this.order = order;
}
@Override
public GatewayFilter apply(Object config) {
return new InnerFilter();
}
/**
* 创建⼀个内部类,来实现2个接⼝,指定顺序
*/
private class InnerFilter implements GatewayFilter, Ordered {
@Override
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println(" pre ⾃定义过滤器⼯⼚ " + this.getClass().getSimpleName());
// 在then⽅法⾥的,相当于aop中的后置通知
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println(" post ⾃定义过滤器⼯⼚ " + this.getClass().getSimpleName());
SpringBoot使用过滤器和拦截器分别实现REST接口简易安全认证示例代码详解
SpringBoot使⽤过滤器和拦截器分别实现REST接⼝简易
安全认证⽰例代码详解
本⽂通过⼀个简易安全认证⽰例的开发实践,理解过滤器和拦截器的⼯作原理。
很多⽂章都将过滤器(Filter)、拦截器(Interceptor)和监听器(Listener)这三者和Spring关联起来讲解,并认为过滤器
(Filter)、拦截器(Interceptor)和监听器(Listener)是Spring提供的应⽤⼴泛的组件功能。
但是严格来说,过滤器和监听器属于Servlet范畴的API,和Spring没什么关系。
因为过滤器继承⾃javax.servlet.Filter接⼝,监听器继承⾃javax.servlet.ServletContextListener接⼝,只有拦截器继承的是
org.springframework.web.servlet.HandlerInterceptor接⼝。
上⾯的流程图参考⾃⽹上资料,⼀图胜千⾔。看完本⽂以后,将对过滤器和拦截器的调⽤过程会有更深刻理解。
⼀、安全认证设计思路
有时候内外⽹调⽤API,对安全性的要求不⼀样,很多情况下外⽹调⽤API的种种限制在内⽹根本没有必要,但是⽹关部署的
时候,可能因为成本和复杂度等问题,内外⽹要调⽤的API会部署在⼀起。
实现REST接⼝的安全性,可以通过成熟框架如Spring Security或者 shiro 搞定。
但是因为安全框架往往实现复杂(我数了下Spring Security,洋洋洒洒⼤概有11个核⼼模块,shiro的源码代码量也⽐较惊
⼈)同时可能要引⼊复杂配置(能不能让⼈痛快⼀点),不利于中⼩团队的灵活快速开发、部署及问题排查。
很多团队⾃⼰造轮⼦实现安全认证,本⽂这个简易认证⽰例参考⾃我所在的前⼚开发团队,可以认为是个基于token的安全认
证服务。
⼤致设计思路如下:
1、⾃定义http请求头,每次调⽤API都在请求头⾥传⼈⼀个token值
2、token放在缓存(如redis)中,根据业务和API的不同设置不同策略的过期时间
SpringBoot——AOP注解式拦截与方法规则拦截
SpringBoot——AOP注解式拦截与⽅法规则拦截
AspectJ是⼀个⾯向切⾯的框架,它扩展了Java语⾔。AspectJ定义了AOP语法,所以它有⼀个专门的编译器⽤来⽣成遵守Java字节编
码规范的Class⽂件。
SpringBoot中AOP的使⽤⽅式主要有两种:注解式拦截与⽅法规则拦截,具体使⽤如下⽂所⽰。
⼀、创建⼀个简单springboot 2.03项⽬,添加aop依赖
org.springframework.boot
spring-boot-starter-aop
此依赖已包含AspectJ相关依赖包。
⼆、编写拦截规则的注解
package com.cenobitor.aop.annotation;
import ng.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
String name();
}
注解说明:元注解是指注解的注解,包括@Retention @Target @Document @Inherited四种。
1.@Retention: 定义注解的保留策略
@Retention(RetentionPolicy.SOURCE) //注解仅存在于源码中,在class字节码⽂件中不包含
@Retention(RetentionPolicy.CLASS) // 默认的保留策略,注解会在class字节码⽂件中存在,但运⾏时⽆法获得,
@Retention(RetentionPolicy.RUNTIME) // 注解会在class字节码⽂件中存在,在运⾏时可以通过反射获取到
⾸先要明确⽣命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作⽤的地⽅后者⼀定也能作⽤。⼀般如果需要在运⾏时去动态
Spring AOP原理及拦截器 2
原理
AOP(Aspect Oriented Programming),也就是面向方面编程的技术。AOP基于IoC根底,是对OOP的有益补充。
AOP将应用系统分为两局部,核心业务逻辑〔Core business
concerns〕及横向的通用逻辑,也就是所谓的方面Crosscutting
enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理〔Persistent〕、事务管理〔Transaction Management〕、平安管理〔Security〕、日志管理〔Logging〕和调试管理〔Debugging〕等。
AOP正在成为软件开发的下一个光环。使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。
Spring framework是很有前途的AOP技术。作为一种非侵略性的、轻型的AOP framework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP
framework,其他人还是像往常一样编程。
AOP概念
让我们从定义一些重要的AOP概念开场。 .
word版 — 方面〔Aspect〕:一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。
— 连接点〔Joinpoint〕:程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
— 通知〔Advice〕:在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around〞、“before〞和“throws〞通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕〞连接点的拦截器链。
— 切入点〔Pointcut〕:指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正那么表达式。
