原文地址:blog.csdn.net/u010922732/…
关键技术
之前我们介绍了 Springboot 如何通过注解方式实现 Filter、Servlet、Listener 组件的功能,除此之外还有另一种通过创建RegistrationBean
相应子类,借助@Bean
注解将自定义组件注册到容器中的方法,一起来看下。
Springboot 提供了三个RegistrationBean
的子类用于注册 Filter、Servlet、Listener 组件:
- FilterRegistrationBean
- ServletRegistrationBean
- ServletListenerRegistrationBean
准备工作
1. 配置 POM 依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sdsj</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<!-- Add typical dependencies for a web application -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!-- Package as an executable jar -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
复制代码
2. 创建启动类和控制器
为了方便,我将启动类和控制器放在一起,如下:
package com.sdsj.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
@RequestMapping("/")
public String index() {
System.out.println("This is index page");
return "Welcome!";
}
}
复制代码
在启动类上添加了两个注解:@SpringBootApplication
和@RestController
。
创建 Filter、Servlet、Listener 类
1. 创建 Filter 类
package com.sdsj.springboot.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/** * 过滤器 * * @author zjhuang * @create 2019/6/4 15:21 **/
public class SecondFilter implements Filter {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void init(FilterConfig filterConfig) throws ServletException {
log.info("second filter init, filter name: " + filterConfig.getFilterName());
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
log.info("second filter uri: " + ((HttpServletRequest) servletRequest).getServletPath());
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
log.info("second filter destroy");
}
}
复制代码
2. 创建 Servlet 类
package com.sdsj.springboot.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/** * 自定义Servlet * * @author zjhuang * @create 2019/6/4 17:13 **/
public class SecondServlet extends HttpServlet {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void init(ServletConfig servletConfig) throws ServletException {
log.info("second servlet init, servlet name: " + servletConfig.getServletName());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
log.info("second servlet uri: " + req.getServletPath());
PrintWriter out = resp.getWriter();
out.write("second servlet is running");
out.flush();
}
@Override
public void destroy() {
log.info("second servlet destroy");
}
}
复制代码
3. 创建 Listener 类
package com.sdsj.springboot.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.http.HttpServletRequest;
/** * 监听器 * * @author zjhuang * @create 2019/6/4 15:21 **/
public class SecondListener implements ServletRequestListener {
private Logger log = LoggerFactory.getLogger(this.getClass());
@Override
public void requestDestroyed(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
log.info("second listener has sent response, uri: " + request.getServletPath());
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
HttpServletRequest request = (HttpServletRequest) sre.getServletRequest();
log.info("second listener has received request, uri: " + request.getServletPath());
}
}
复制代码
注册 Filter、Servlet、Listener
package com.sdsj.springboot.config;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import java.util.EventListener;
/** * 全局配置类 * * @author zjhuang * @create 2019/6/5 17:39 **/
@Configuration
public class Config {
/** * 注册一个Filter * * @return FilterRegistrationBean */
@Bean
public FilterRegistrationBean registerFilter() {
// 创建Filter注册Bean
FilterRegistrationBean<Filter> registration = new FilterRegistrationBean<>();
// 创建自定义的Filter对象
SecondFilter filter = new SecondFilter();
// 注册Filter
registration.setFilter(filter);
// 设置Filter名称
registration.setName("second_filter");
// 设置Fliter匹配规则
registration.addUrlPatterns("/*");
// 设置排序,在存在多个Filter实例的情况下确定Filter的执行顺序
registration.setOrder(1);
return registration;
}
/** * 注册一个Servlet * * @return ServletRegistrationBean */
@Bean
public ServletRegistrationBean registerServlet() {
// 创建Servlet注册Bean
ServletRegistrationBean<Servlet> registration = new ServletRegistrationBean<>();
// 创建自定义的Servlet对象
SecondServlet servlet = new SecondServlet();
// 注册Servlet
registration.setServlet(servlet);
// 设置Servlet名称
registration.setName("second_servlet");
// 设置Servlet配置规则
registration.addUrlMappings("/second_servlet");
// 设置加载参数
registration.setLoadOnStartup(1);
return registration;
}
/** * 注册一个Listener * * @return ServletListenerRegistrationBean */
@Bean
public ServletListenerRegistrationBean registerListener() {
// 创建Listener注册Bean
ServletListenerRegistrationBean<EventListener> registration = new ServletListenerRegistrationBean<>();
// 创建自定义的Listener对象
SecondListener listener = new SecondListener();
// 注册Listener
registration.setListener(listener);
// 设置排序,在存在多个Listener实例的情况下确定Listener的执行顺序
registration.setOrder(1);
return registration;
}
}
复制代码
扩展
Spring Boot 为了方便大家向 Servlet 容器中注册 Servlet、Filter 以及 Listener,提供了一个 Bean 注册的抽象类RegistrationBean
,如下:
public abstract class RegistrationBean implements ServletContextInitializer, Ordered {
private int order = Ordered.LOWEST_PRECEDENCE;
private boolean enabled = true;
@Override
public final void onStartup(ServletContext servletContext) throws ServletException {
String description = getDescription();
if (!isEnabled()) {
logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
return;
}
register(description, servletContext);
}
protected abstract String getDescription();
protected abstract void register(String description, ServletContext servletContext);
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public boolean isEnabled() {
return this.enabled;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public int getOrder() {
return this.order;
}
}
复制代码
RegistrationBean
实现了 ServletContextInitializer
接口,在 Servlet 启动时,RegistrationBean#onStartup
方法会被调用,进而完成 Filter、Servlet 以及 Listener 的注册。
SprinngBoot提供了如下所示的RegistrationBean实现类:
ServletListenerRegistrationBean
用来注册监听器。ServletRegistrationBean
用来注册 Servlet。DispatcherServletRegistrationBean
用来注册 DispatcherServlet。FilterRegistrationBean
用来注册过滤器。DelegatingFilterProxyRegistrationBean
则用来注册 DelegatingFilterProxy,DelegatingFilterProxy 在 Spring Security、Spring Session、Shiro 等整合时非常有用。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。