Spring Interceptor Filter 拦截器和过滤器

一、结论

拦截器(Interceptor)和过滤器(Filter)的区别:

①拦截器是基于java的反射机制的,而过滤器是基于函数回调。

②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。

③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。

④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。

⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。

⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。

拦截器(Interceptor)可以获取ioc中的service bean实现业务逻辑

二、触发时机

有个专业词语叫触发时机

  1. 过滤器(Filter)和拦截器(Interceptor)触发时机不一样:

    过滤器是在请求进入容器后,但请求进入servlet之前进行预处理的。请求结束返回也是,是在servlet处理完后,返回给前端之前。

总结:过滤器包裹住servlet,servlet包裹住拦截器。

  1. 过滤器的触发时机是容器后,servlet之前,所以过滤器的doFilter(ServletRequest request, ServletResponse response, FilterChain chain)的入参是ServletRequest ,而不是HttpServletRequest。因为过滤器是在HttpServletRequest之前。
  2. 过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
  3. 拦截器(Interceptor)是被包裹在过滤器之中的。
    5. SpringMVC的机制是由同一个Servlet来分发请求给不同的Controller,其实这一步是在Servlet的service()方法中执行的。
  4. 拦截器是spring容器的,是spring支持的,

三、画图说明

graph TD;
A[Filter] -->|处理请求| B[tomcat];
B -->|调用拦截器链| C[Interceptor];
C -->|调用servlet| D[servlet];
D -->|调用controller| E[controller];

在Tomcat中,当请求到达服务器后,首先会经过过滤器(Filter)。Filter可以对请求进行预处理和过滤,比如身份认证、日志记录、字符编码等。而Servlet是基于Java编写的Web应用程序,是在请求经过过滤器后,由Tomcat调用Servlet容器进行处理。Controller是MVC框架中的一部分,它主要负责接收请求并根据请求的类型和参数调用相应的业务逻辑进行处理。拦截器(Interceptor)则是在Servlet容器处理请求之前或之后对请求进行处理,比如权限控制、日志记录、性能监控等。

因此,Filter需要在Servlet容器之前进行过滤处理,拦截器可以在Servlet容器之前或之后进行拦截处理。这样,可以保证请求在经过Filter和Interceptor进行预处理和过滤之后再交由Servlet进行业务逻辑处理。

请求会先到达Tomcat服务器。但是在请求到达Servlet之前,会经过一系列的Filter和Interceptor,这些组件可以对请求进行预处理、过滤、验证等操作,然后再将请求交给Servlet进行处理。因此,Filter和Interceptor是在Tomcat之前起作用的。

请求 -----------> 过滤器(Filter) -----------> 拦截器(Interceptor) -----------> Tomcat -----------> Servlet -----------> Controller

请求会先经过Filter,Filter会对请求进行过滤,比如判断是否符合某些条件,然后才会进入到Tomcat,Tomcat会将请求分发到对应的Servlet,Servlet会对请求进行处理并生成响应,最终响应会被返回到Controller中进行处理。在这个过程中,Interceptor可以对请求和响应进行拦截,并且可以在进入Servlet之前或者之后进行一些处理。整个过程的顺序是Filter->Tomcat->Servlet->Controller,Interceptor可以在任意一个环节进行拦截。

Spring Boot 注解 常用注解说明

Spring Boot是一个快速开发框架,快速的将一些常用的第三方依赖整合(通过Maven子父亲工程的方式),简化xml配置,全部采用注解形式,内置Http服务器(Jetty和Tomcat),最终以Java应用程序进行执行。Spring DIP

一、注解Controller 和 RestController

RestController的作用相当于Controller加ResponseBody共同作用的结果,但采用RestController请求方式一般会采用Restful风格的形式。

Controller的作用:声明该类是Controller层的Bean,将该类声明进入Spring容器中进行管理

ResponseBody的作用:表明该类的所有方法的返回值都直接进行提交而不经过视图解析器,且返回值的数据自动封装为json的数据格式

RestController的作用:包含上面两个的作用,且支持Restful风格的数据提交方式

Restful风格:

    get:获取数据时用的请求方式

    post:增加数据时的请求方式

    put:更新数据时的请求方式

    delete:删除数据时的请求方式

在每个Controller类的上边加速注解,用于形成API接口交付给前端

二、@NoArgsConstructor、@AllArgsConstructor、@RequiredArgsConstructor

区别:

  • @NoArgsConstructor:生成无参的构造方法。
  • @AllArgsConstructor:生成该类下全部属性的构造方法。
  • @RequiredArgsConstructor:生成该类下被final修饰或者non-null字段生成一个构造方法。

场景:

在springboot中,对于一个bean类,注入其他bean的时候,常见的是使用@Autowired,实际上也可以使用构造函数注入,
这个时候就可以使用@AllArgsConstructor或者@RequiredArgsConstructor来代替。

三、泛型

以下代码编译器会报错(com.yang.memorytest.Person.this’ cannot be referenced from a static context),因为泛型类型只有在类实例化的时候才确定,而静态方法可以直接通过类来调用;

如果静态方法需要使用泛型,可以在方法定义泛型,

    public class Person {    
        public static <T>void a(T data){        
        }
    }
    public static <T> Result<T> sucess(){
        return new Result<>(20008, "sucess", null);
    }

四、@Resource @Autowired

spring的管理机制Bean工厂已经把对象创建好了 你只需要调用就行!

一般代码中对象普遍是new Class把对象实例出来,注入之后呢,spring帮你new好了,你可以直接用了

@Resource主要做依赖注入,从容器中自动获取bean,作用如下:

在启动Spring时,首先要启动容器
在启动Sprng容器时,会默认寻找容器扫描范围内的可加载的bean,然后查找哪些bean上的属性和方法有@resource注解
找到@resource注解后,判断其name属性是否为空,若为空,看Spring容器中的bean中的id与@resource要注解的那个变量属性名是否相同,如相同,匹配成功;如不同,看spring容器中bean的id对应的类型是否与@resource要注解的那个变量属性对应的类型是否相等,若相等,匹配成功,若不相等,匹配失败
如果@resource注解括号中的name属性不为空,看name的属性值和容器中的bean的id名是否相等,如相等,则匹配成功,如果不相等,则匹配失败

@Resource和@Autowired注解都是用来实现依赖注入的。只是@Autowired按by type自动注入,而@Resource默认按by name自动注入

@Autowired 和 @Resource 都是用来实现依赖注入的注解(在 Spring/Spring Boot 项目中),但二者却有着 5 点不同:

来源不同:@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250;
依赖查找的顺序不同:@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询;
支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数;
依赖注入的用法支持不同:@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入;
编译器 IDEA 的提示不同:当注入 Mapper 对象时,使用 @Autowired 注解编译器会提示错误,而使用 @Resource 注解则不会提示错误。

https://www.jb51.net/article/260980.htm

五、@Component和@Bean

  1. @Component 和 @Bean 是两种使用注解来定义bean的方式。

  2. @Component(和@Service和@Repository)用于自动检测和使用类路径扫描自动配置bean。注释类和bean之间存在隐式的一对一映射(即每个类一个bean)。这种方法对需要进行逻辑处理的控制非常有限,因为它纯粹是声明性的。

  3. @Bean用于显式声明单个bean,而不是让Spring像上面那样自动执行它。它将bean的声明与类定义分离,并允许您精确地创建和配置bean。

  4. @Bean则常和@Configuration注解搭配使用

    1.Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。
    
    2.Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册成Spring应用上下文中的bean。通常方法体包含了最终产生bean实例的逻辑。
  5. @Autowired或者@Resource注解注入

  6. 为什么有了@Compent,还需要@Bean呢?

    如果想将第三方的类变成组件,你又没有没有源代码,也就没办法使用@Component进行自动配置,这种时候使用@Bean就比较合适了。不过同样的也可以通过xml方式来定义。
    
    另外@Bean注解的方法返回值是对象,可以在方法中为对象设置属性。
    
    另外了解一下Spring的Starter机制,就是通过@Bean注解来定义bean。可以搭配@ConditionalOnMissingBean注解 
    
    @ConditionalOnMissingClass注解,如果本项目中没有定义该类型的bean则会生效。避免在某个项目中定义或者通过congfig注解来声明大量重复的bean。

区别:

- Component通常是通过类路径扫描来自动侦测以及自动装配到Spring容器中
- Bean注解通常是我们在标有该注解的方法中定义产生这个bean的逻辑。
- Component用在类上,Bean用在方法上。