概述
SpringBoot 借助 Servlet 3.1 新特性实现零配置的原理
- 简介
- 放置 ServletContainerInitializer 实现类的全路径
- 设计想要被调用的类及其接口
- 接口
- 实现类
- Servlet 将调用此类
- 启动 Tomcat 看效果
- 参考资料
简介
- Servlet 3.1 搞了个类似开机自动运行的规则。(但是我貌似 3.0 也跑起来了,不知道是不是我搞错了什么)
- 1、创建此类,类名随意别作死就行。实现接口 javax.servlet.ServletContainerInitializer
- 2、将此类全路径名,放到这个文件中:【/项目/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer】
- 3、Servlet容器跑起来后,自动调用当前类的 onStartup
- 4、onStartup 的参数 Set<Class<?>> 就是当前项目所有实现了 @HandlesTypes(IJerryAppInitializer.class) 接口的类。
- 5、通过反射,玩转 JerryAppInitializer ()
放置 ServletContainerInitializer 实现类的全路径
servlet
通过它来找到我们创建的类(实现了 ServletContainerInitializer
接口 ),并运行 JerryServletContainerInitializer#onStartup()
/demo/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
com.jerry.demo.JerryServletContainerInitializer
设计想要被调用的类及其接口
接口
目的是让所有实现了该接口的类都被自动调用。
/demo/src/main/java/com/jerry/service/IJerryAppInitializer.java
package com.jerry.service;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
public interface IJerryAppInitializer {
// 这个名字自己取得
void onJerryStartup(ServletContext servletContext) throws ServletException;
}
实现类
实现我们自定的接口,处理具体业务逻辑。比如注册 servlet
进行配置等。以实现编程式
配置
/demo/src/main/java/com/jerry/service/impl/JerryAppInitializer.java
package com.jerry.service.impl;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import com.jerry.service.IJerryAppInitializer;
public class JerryAppInitializer implements IJerryAppInitializer{
@Override
public void onJerryStartup(ServletContext servletContext) throws ServletException {
System.out.println("我是 com.jerry.service.impl.JerryApplicationInitializer,我是被 /demo/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer 折腾起来的。");
}
}
Servlet 将调用此类
Servlet
将调用此类,此类再调用我上面定义的【想要被调用的类
】
在此类中,我们能获得所有IJerryAppInitializer
的实现类的实例(系统通过 onStartup
的参数Set<Class<?>> xxx
传给我们)。并通过反射调用其方法。
/demo/src/main/java/com/jerry/demo/JerryServletContainerInitializer.java
package com.jerry.demo;
import java.lang.reflect.Modifier;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.HandlesTypes;
import com.jerry.service.IJerryAppInitializer;
/**
* Servlet 3.1 搞了个类似开机自动运行的规则。
* 1、创建此类,类名随意别作死就行。实现接口 javax.servlet.ServletContainerInitializer
* 2、将此类全路径名,放到这个文件中:【/项目/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer】
* 3、Servlet容器跑起来后,自动调用当前类的 onStartup
* 4、onStartup 的参数 Set<Class<?>> 就是当前项目所有实现了 @HandlesTypes(IJerryAppInitializer.class) 接口的类。
* 5、通过反射,玩转 JerryAppInitializer ()
* @author jerryjin
*/
@HandlesTypes(IJerryAppInitializer.class)
public class JerryServletContainerInitializer implements ServletContainerInitializer {
@Override
public void onStartup(Set<Class<?>> jerryAppInitializerClasses, ServletContext servletContext) throws ServletException {
System.out.println("servlet3.1 规定的 javax.servlet.ServletContainerInitializer 跑起来了");
List<IJerryAppInitializer> initializers = new LinkedList<>();
if (jerryAppInitializerClasses != null) {
for (Class<?> clazz : jerryAppInitializerClasses) {
if (!clazz.isInterface()
&& !Modifier.isAbstract(clazz.getModifiers())
&& IJerryAppInitializer.class.isAssignableFrom(clazz))
{
try {
initializers.add((IJerryAppInitializer)clazz.newInstance());
}
catch (Throwable ex) {
throw new ServletException("实例化 JerryAppInitializer 失败!", ex);
}
}
}
}
if (initializers.isEmpty()) {
servletContext.log("木有找到 com.jerry.service.IJerryAppInitializer");
return;
}
servletContext.log(initializers.size() + "个 IJerryAppInitializer 实现类在 classpath 出没");
for (IJerryAppInitializer initializer : initializers) {
//
initializer.onJerryStartup(servletContext);
}
}
}
启动 Tomcat 看效果
。。。
servlet3.1 规定的 javax.servlet.ServletContainerInitializer 跑起来了
我是 com.jerry.service.impl.JerryApplicationInitializer,我是被 /demo/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer 折腾起来的。
信息: 1个 IJerryAppInitializer 实现类在 classpath 出没
。。。
参考资料
【鲁班学院】2019全网最全面的spring boot源码分析
org.springframework.web.WebApplicationInitializer.java
org.springframework.web.SpringServletContainerInitializer.java
最后
以上就是细心斑马为你收集整理的SpringBoot 借助 Servlet 3.1 新特性实现零配置的原理简介放置 ServletContainerInitializer 实现类的全路径设计想要被调用的类及其接口Servlet 将调用此类启动 Tomcat 看效果参考资料的全部内容,希望文章能够帮你解决SpringBoot 借助 Servlet 3.1 新特性实现零配置的原理简介放置 ServletContainerInitializer 实现类的全路径设计想要被调用的类及其接口Servlet 将调用此类启动 Tomcat 看效果参考资料所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复