概述
问题: spring web,在没有web.xml的情况下是如何被tomcat拉起来启动的呢?
首先是,tomcat 会通过 java 的spi 机制(其实tomcat 没java提供的spi方式,只是参照了其规范而已,下面详述),去找 javax.servlet.ServletContainerInitializer (since servlet 3.0)的实现类sping-web jar里有对 ServletContainerInitializer 的实现 SpringServletContainerInitializer 。
然后,tomcat 会调用该接口实现的 onStart 方法。这样就将执行权交给了 spring了。
java 的spi 机制:
- java 1.6 开始提供一个类叫做 java.util.ServiceLoader, 它是finnal 的,无法被继承个改动。
- 它有load(Class aClass) 方法,这个方法会去所以jar 中寻找 /META-INF/services/${aClass.fullClassName} 的文件(使用 ClassLoader.getSystemResources 方法),全部找到,然后解析其里面的内容,里面按照规范应该是每行一个对aClass 的一个实现类。并会通过 Class 的 newInstance 将其创建实例后给出来。 如此,调用者即可通过ServiceLoader 类的load 方法,找到实现了某个接口的 实现类并操作其实例。
- 然而 servlet3.0 并没有直接使用上面说的 java 的spi方式。只是参照其标准,自己写了个 WebappServiceLoader ,其虽然也是找 /META-INF/service 下的东西,但是找的范围被限定在 /WEB-INF/lib 下的jar中。
然后说说 ServletContainerInitializer 这个规范:
- 其 实现类 通过 spi 方式被找到后, 如果实现类上被注解了 类似 @javax.servlet.annotation.HandlesTypes(A.class,B.class) ,那么调用者按照规范需要将 A.class和 B.class 的实现类的 Class 对象,弄个Set ,传递给这个 ServletContainerInitializer 的 onStart 方法的第一个参数中。servlet3.0 是通过BCEL框架来扫描HandlesTypes中指定接口的实现类的。 Byte Code Engineering Library (BCEL),这是Apache Software Foundation 的Jakarta 项目的一部分,作用同ASM类似,是字节码操纵框架。
最后
以上就是敏感柚子为你收集整理的java spi ,servlet3.0 spring web启动的全部内容,希望文章能够帮你解决java spi ,servlet3.0 spring web启动所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复