通过Spring Bean 来添加 Servlet、Filter 和 Listener
★ 添加Web组件(Servlet、Filter、Listener)的三种方式:
- 使用Spring Bean添加Servlet、Filter或Listener。- 使用XxxRegistrationBean手动添加Servlet、Filter或Listener。- 使用ClassPath扫描添加Servlet、Filter和Listener。
★ 第一种方式:使用Spring Bean添加Servlet、Filter或Listener
——只要将这些Web组件配置成容器中Bean即可。
Spring Boot会自动将这些特殊的bean注册成Web组件。通过这种方式添加的Servlet、Filter或Listener,由于它们都是Spring容器中的Bean,非常方便地利用Spring的依赖注入。因此可以可以方便地访问application.properties中配置的属性值,也可利用依赖注入将Spring容器中的其他Bean注入这些Servlet、Filter或Listener。当Spring容器中只有一个Servlet时,它默认被映射到应用的根路径(/);当Spring容器中有包含多个Servlet时,它们的映射地址就是它们的Bean名称(name属性值),别忘了后面必须带一个斜杠结尾。而Filter的映射地址则默认为/*。
浏览器访问这些bean的注意点:
对这些bean进行访问,由于把Servlet、Filter 和 Listener 配置成了spring容器中的bean,所以没有办法为它们指定映射地址,所以springboot就会给默认给它们一个映射地址。
当Spring容器中只有一个Servlet时,它默认被映射到应用的根路径(/);
当Spring容器中有包含多个Servlet时,它们的映射地址就是它们的Bean名称(name属性值),而且访问的时候,bean的名称的首字母要小写,别忘了后面必须带一个斜杠结尾(为什么加斜杠?因为springboot就是这么规定的)。
也可以在注解上这么显式指定名称,在Component注解显式指定为first,那么这个FirstServlet的Bean的id或者是name属性(就是类名)就变成了 first,访问的时候就不再是firstServlet而是first
代码演示:
先创建servlet、filter 和 listener 这三个bean。
1、创建两个 servlet ,后面用来演示 访问路径的注意点
用 @Component 修饰,这个类将成为spring容器中的一个bean,springboot会自动将它注册为 Servlet bean
创建 Filter 过滤器
用 @Component 修饰,这个类将成为spring容器中的一个bean,springboot会自动将它注册为 Filter 过滤器bean
创建 Listener 监听器
用 @Component 修饰,这个类将成为spring容器中的一个bean,springboot会自动将它注册为 Listener 监听器bean
测试:
启动项目,走了 filter 过滤器 和 listener 监听器 这个两个bean的一些方法
访问 servlet ,走了过滤器的 doFilter 过滤方法
关闭项目,走过滤器和监听器的方法。
总结:从启动项目,访问 servlet 这个bean ,到关闭项目,过滤器和监听器的方法都有执行到。
启动项目:Filter 过滤器的 init 初始化方法,Listener 监听器的 contextInitialized web应用初始化时被触发的方法。
访问 servlet 这个bean:执行 Servlet bean的代码设置,如 writer 方法输出字符串到浏览器页面,也走了过滤器的 doFilter 过滤方法
关闭项目:执行了 Filter 过滤器的 destroy 销毁方法,执行了 Listener 监听器的 contextDestroyed web应用销毁时被触发的方法
★ 第二种方式:使用XxxRegistrationBean来注册Servlet、Filter或Listener
在容器中配置XxxRegistrationBean可注册Web组件,每个注册Bean注册一个Web组件- ServletRegistrationBean 注册 Servlet。- FilterRegistrationBean 注册 Filter。- ServletListenerRegistrationBean 注册 Listener.通过这种方式注册时,开发者可获得对Web组件全部的控制权,
它们也不是Spring容器中的Bean,因此不会自动接收依赖注入。【备注】:虽然通过这种方式来注册Web组件时,它们不能自动接受Spring容器的依赖注入但由于这种方式可以获得Web组件的全部控制权,因此可以现在配置类中使用依赖注入,然后将被注入的值传递给web组件,因此这些Web组件同样可以获取Spring Boot应用的配置属性。
代码演示:
因为第一种方法使用的是把Servlet、Filter、Listener 通过 @Component 修饰成spring容器中的bean,添加这个注解spring容器就会把这三个注册成组件。
现在是要使用XxxRegistrationBean来注册Servlet、Filter或Listener,所以还用上面的三个类,只是不用 @Component 来修饰成组件。把原本的 @Component 注解去掉,让它们三个变成普通类。
然后创建一个配置类,在配置类里面通过 XxxRegistrationBean 将 Servlet、Filter、Listener 一个一个配置bean,来对它们进行注册。
测试:在配置类里面通过 XxxRegistrationBean 注册 Servlet、Filter、Listener 的这些组件都生效。
注意:如果该类不是spring容器中的bean,那么该类就没法使用依赖注入,不会生效。如图
FirstServlet 这个类把原本的 message 依赖注入直接改成普通的成员变量,然后给一个set方法
然后再 配置类里面,因为配置类是spring容器中的一个bean,所以能进行依赖注入,可以拿到yml配置中的 message 属性值,然后把值set 给 firstServlet 这个实例对象就可以了。
★ 第三中方式:使用Classpath扫描的方式来注册Web组件:
这种方式很方便,只要两步:
(1)为Web组件添加@WebServlet、@WebFilter或@WebListener注解。
(2)使用@ServletComponentScan注解告诉Spring Boot去扫描、注册Web组件。
这些注解不属于spring,也不属于springboot,属于java web 规范的,所以默认springboot是不识别的,需要再通过@ServletComponentScan注解告诉Spring Boot去扫描、注册Web组件。通过这种方式添加的Web组件依然是Spring容器中的Bean,因此它们同样可接受依赖注入。而且用起来很方便,可以为它们指定映射地址。因此推荐使用这种方式
【注意:】 由于Listener的启动时机非常早,因此Listener在监听到Web应用时,没有获取依赖注入的值。
代码演示:
把三个类拷贝到另一个包里面来进行第三种方法的注册web组件
因为用这些注解后,也是把这三个注册到spring容器中的bean,所以也能进行依赖注入。
测试: 注册 Servlet、Filter、Listener 的这些组件都生效。
依赖注入也有效果,因为它们都是spring容器中的bean