1、SpringBoot配置自定义监听器
实质上是在servlet3.0+的容器中,注册一个Servlet。
功能:监听对应的请求路径url-api
@Slf4j
@Configuration
public class SpringBootAutoConfigure
{
// 配置监听器
@Bean("xxxListener")
public ServletRegistrationBean<XxxServlet> createtListener()
{
log.info("监听请求的路径 /url-api...");
ServletRegistrationBean<XxxServlet> bean = new ServletRegistrationBean<>(
new XxxServlet());
//添加参数至LinkedHashMap
bean.addInitParameter("aaaController", "aaaController");
bean.addInitParameter("bbbController", "bbbController");
bean.addUrlMappings("/url-api");
return bean;
}
}
// 设置参数的方法
public void setInitParameters(Map<String, String> initParameters) {
Assert.notNull(initParameters, "InitParameters must not be null");
this.initParameters = new LinkedHashMap<>(initParameters);
}
2、如何注册Servlet
首先看看类和接口之间的依赖模型:
增加Servlet, ServletRegistrationBean使用泛型限定这个类是Servlet,通过构造函数参数为Servlet的对象,
注册在Servlet一个servlet3.0+的容器中。
public ServletRegistrationBean(T servlet, String... urlMappings) {
this(servlet, true, urlMappings);
}
2.1 ServletRegistrationBean
Servlet的设置和获取,MapperURL的设置添加等等
public class ServletRegistrationBean<T extends Servlet> extends DynamicRegistrationBean<ServletRegistration.Dynamic> {
private static final String[] DEFAULT_MAPPINGS = { "/*" };
private T servlet;
private Set<String> urlMappings = new LinkedHashSet<>();
private boolean alwaysMapUrl = true;
private int loadOnStartup = -1;
private MultipartConfigElement multipartConfig;
2.2 设置参数
public abstract class DynamicRegistrationBean<D extends Registration.Dynamic> extends RegistrationBean {
private static final Log logger = LogFactory.getLog(RegistrationBean.class);
private String name;
private boolean asyncSupported = true;
private Map<String, String> initParameters = new LinkedHashMap<>();
2.3 RegistrationBean
可以设置Servlet的启动顺序,实现了ServletContextInitializer的类将会被SpringServletContainerInitializer监测到
public abstract class RegistrationBean implements ServletContextInitializer, Ordered {
private static final Log logger = LogFactory.getLog(RegistrationBean.class);
private int order = Ordered.LOWEST_PRECEDENCE;
private boolean enabled = true;
2.4 接口ServletContextInitializer和Ordered
@FunctionalInterface
public interface ServletContextInitializer {
public interface Ordered {
/**
* Useful constant for the highest precedence value.
* @see java.lang.Integer#MIN_VALUE
*/
int HIGHEST_PRECEDENCE = Integer.MIN_VALUE;
/**
* Useful constant for the lowest precedence value.
* @see java.lang.Integer#MAX_VALUE
*/
int LOWEST_PRECEDENCE = Integer.MAX_VALUE;
3、常见的初始化接口
3.1 ServletContainerInitializer
org.springframework.web.SpringServletContainerInitializer is an implementation of javax.servlet.ServletContainerInitializer.
与传统基于web.xml的配置方式不同,Servlet3.0设计了ServletContainerInitializer,ServletContainerInitializer
支持通过Spring的WebApplicationInitializer SPI编写基于代码的Servlet容器配置。
3.2 WebApplicationInitializer接口几种配置ServletContext的方式
1 传统的web.xml,代码示例
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2 实现这个接口WebApplicationInitializer ,代码示例。主要复写onStartup方法。
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
3 基于代码方式的全配置,代码示例。
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
3.3 org.springframework.boot.web.support.SpringBootServletInitializer (class)
这是一个通过传统的WAR包部署方式运行SpringApplication的WebApplicationInitializer实现。它可以将应用容器中的Servlet、
Filter和ServletContextInitializer相关的bean绑定到服务器(ServletContainer)。
3.4 org.springframework.boot.web.servlet.ServletContextInitializer (interface)
不同于WebApplicationInitializer,该接口的实现类不会被SpringServletContainerInitializer识别因此不会被Servlet容器自动执行。
ServletContextInitializers主要被Spring管理而不是Servlet容器。