Spring boot传统部署
使用spring boot很方便,一个jar包就可以启动了,因为它里面内嵌了tomcat等服务器。
但是spring boot也提供了部署到独立服务器的方法。
如果你看文档的话,从jar转换为war包很简单,pom.xml的配置修改略去不讲。
只看source的修改,很简单,只要一个配置类,继承自SpringBootServletInitializer, 并覆盖configure方法。
@SpringBootApplication public class TestApplication extends SpringBootServletInitializer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { return builder.sources(TestApplication .class); } public static void main(String[] args) { SpringApplication.run(FocusTripApplication.class, args); } }
对,你没看错,就这么简单。
但是,我觉得但凡有点儿好奇心的人都不甘于就这么用它,总会想知道为啥这样就行了?
那么我们根据调用关系来弄个究竟。
SpringBootServletInitializer.configure
<-createRootApplicationContext
<-onStartup
<-SpringServletContainerInitializer.onStartup
SpringServletContainerInitializer这个类比较特殊,实现的是interface ServletContainerInitializer,这个类的onStartup方法,是由tomcat调用了。
那么tomcat是怎么找到它的呢?是搜寻的这个资源文件META-INF/services/javax.servlet.ServletContainerInitializer
而在spring的包spring-web-xxxx.jar包里正好有这个文件,它注册的恰恰就是这个类
这个类有个注解@HandlesTypes(WebApplicationInitializer.class)。
调用SpringServletContainerInitializer.onStartup方法时,会把所有的WebApplicationInitializer类以及子类都传过来。
然后再通过条件过滤一下。
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) { try { initializers.add((WebApplicationInitializer) waiClass.newInstance()); } catch (Throwable ex) { throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex); } }
也就是只要是非interface,且非抽象类,并都是WebApplicationInitializer的字类的话,就会被实例化,并最终调用。
然后,在SpringBootServletInitializer的createRootApplicationContext方法里,最终会初始化SpringApplication,调用其run方法,跟直接运行入口的main方法是一样的了。
已有 0 人发表留言,猛击->> 这里<<-参与讨论
ITeye推荐