Java SPI、servlet3.0与@HandlesTypes源码分析
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java SPI、servlet3.0与@HandlesTypes源码分析,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含2438字,纯文字阅读大概需要4分钟。
内容图文
关于Java SPI与servlet3.0的应用,这里说的很精炼,链接地址如下。
https://blog.csdn.net/pingnanlee/article/details/80940993
以Tomcat8.5.31对Servlet的实现为例,简单提一点,Tomcat获取ServletContainerInitializer的实现类是在org.apache.catalina.startup.ContextConfig.webConfig() 中,Step 3调用processServletContainerInitializers(),
使用了自己的WebappServiceLoader,解释为A variation of Java's JAR ServiceLoader。
顺带一提tomcat启动时webConfig() 的调用链:
Tomcat.start()->各种代理的start()->org.apache.catalina.core.StandardContext.startInternal->LifecycleBase.fireLifecycleEvent->org.apache.catalina.startup.ContextConfig.lifecycleEvent->configureStart->webConfig
另:感叹一下tomcat的源码中,每一个方法都好长,和spring源码的深层次相比简直各有千秋,以及那个叫做ok的boolean 变量,可能相比用异常来表示更为直观吧。
@HandlesTypes的实现原理:
首先这个注解最开始令我非常困惑,他的作用是将注解指定的Class对象作为参数传递到onStartup(ServletContainerInitializer)方法中。
然而这个注解是要留给用户扩展的,他指定的Class对象并没有要继承ServletContainerInitializer,更没有写入META-INF/services/的文件(也不可能写入)中,那么Tomcat是怎么扫描到指定的类的呢。
答案是Byte Code Engineering Library (BCEL),这是Apache Software Foundation 的Jakarta 项目的一部分,作用同ASM类似,是字节码操纵框架。
webConfig() 在调用processServletContainerInitializers()时记录下注解的类名,然后在Step 4和Step 5中都来到processAnnotationsStream这个方法,使用BCEL的ClassParser在字节码层面读取了/WEB-INF/classes和某些jar(应该可以在叫做fragments的概念中指定)中class文件的超类名和实现的接口名,判断是否与记录的注解类名相同,若相同再通过org.apache.catalina.util.Introspection类load为Class对象,最后保存起来,于Step 11中交给org.apache.catalina.core.StandardContext,也就是tomcat实际调用
ServletContainerInitializer.onStartup()的地方。
至此,谜团终于解开。
不过还有一个小疑问,StandardContext存放@HandlesTypes的对象叫做Map<ServletContainerInitializer,Set<Class<?>>> initializers,他的addServletContainerInitializer方法除了webConfig()以外,还被TomcatEmbeddedServletContainerFactory.addJasperInitializer和TomcatEmbeddedServletContainerFactory.configureContext调用,不知道运行起来是否有多余的class混入其中。也难怪spring要在SpringServletContainerInitializer.onstart的处理中这样注释的原因了吧:D
// Be defensive: Some servlet containers provide us with invalid classes,
// no matter what @HandlesTypes says...
不知道其他Servlet,比如Jetty引擎,是怎么实现@HandlesTypes这个注解的呢。
内容总结
以上是互联网集市为您收集整理的Java SPI、servlet3.0与@HandlesTypes源码分析全部内容,希望文章能够帮你解决Java SPI、servlet3.0与@HandlesTypes源码分析所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。