接着分析下start()方法:
Catalina.start() {...
if (getServer() == null) {
load();
getServer().start();...
}
StandardServer.startInternal(){
fireLifecycleEvent(CONFIGURE_START_EVENT, null);
setState(LifecycleState.STARTING);//设置Server状态 触发lisener监听器
globalNamingResources.start();
// Start our defined Services
synchronized (servicesLock) {
for (int i = 0; i < services.length; i++) {
services[i].start();
}
}
}
StandardService.startInternal(){...
setState(LifecycleState.STARTING);
engine.start();
executor.start();
mapperListener.start();//组件添加能监听到
synchronized (connectorsLock) {
for (Connector connector: connectors) {
try {
// If it has already failed, don't try and start it
if (connector.getState() != LifecycleState.FAILED) {
connector.start();...
}
我们看下engine的启动
StandardEngine.startInternal(){
super.startInternal();//ContainerBase...
}
ContainerBase.startInternal(){...
Cluster cluster = getClusterInternal();
if (cluster instanceof Lifecycle) {
((Lifecycle) cluster).start();
}
Realm realm = getRealmInternal();
if (realm instanceof Lifecycle) {
((Lifecycle) realm).start();
}
Container children[] = findChildren();
List<Future<Void>> results = new ArrayList<>();
for (int i = 0; i < children.length; i++) {
results.add(startStopExecutor.submit(new StartChild(children[i])));//启动子节点
}
MultiThrowable multiThrowable = null;
for (Future<Void> result : results) {
try {
result.get();//完成了所有子组件的启动
} catch (Throwable e) {
log.error(sm.getString("containerBase.threadedStartFailed"), e);...
if (pipeline instanceof Lifecycle) {// Start the Valves in our pipeline (including the basic), if any
((Lifecycle) pipeline).start();//把请求给到容易后通过value(类似阀门),然后责任链形式匹配容器上的value。容器就拿到了这个请求
}
setState(LifecycleState.STARTING);
threadStart();// Start our thread
...}
StandardHost.startInternal(){...
String errorValve = getErrorReportValveClass();// Set error report valve
super.startInternal();//Container
}
ContainerBase.startInternal(){...
setState(LifecycleState.STARTING);//激发监听器HostConfig
}
host启动
HostConfig.start() {...
if (host.getDeployOnStartup())
deployApps();//部署app
...}
deployApps() {
File appBase = host.getAppBaseFile();
File configBase = host.getConfigBaseFile();
// 过滤出 webapp 要部署应用的目录
String[] filteredAppPaths = filterAppPaths(appBase.list());
// 部署 xml 描述文件
deployDescriptors(configBase, configBase.list());
// 解压 war 包,但是这里还不会去启动应用
deployWARs(appBase, filteredAppPaths);
// 处理已经存在的目录,前面解压的 war 包不会再行处理
deployDirectories(appBase, filteredAppPaths);
}
deployDirectory(ContextName cn, File dir) {...
context.setName(cn.getName());
context.setPath(cn.getPath());
context.setWebappVersion(cn.getVersion());
context.setDocBase(cn.getBaseName());
host.addChild(context);
...}
context启动
StandardContext.startInternal(){...
// Send j2ee.state.starting notification
if (this.getObjectName() != null) {
Notification notification = new Notification("j2ee.state.starting",
this.getObjectName(), sequenceNumber.getAndIncrement());
broadcaster.sendNotification(notification);
}...
postWorkDirectory();// Post work directory 配置工作目录
fireLifecycleEvent(Lifecycle.CONFIGURE_START_EVENT, null);// Notify our interested LifecycleListeners 触发ContextConfig
...}
ContextConfig.webConfig() {...
WebXmlParser webXmlParser = new WebXmlParser(context.getXmlNamespaceAware(),
context.getXmlValidation(), context.getXmlBlockExternal());
Set<WebXml> defaults = new HashSet<>();
defaults.add(getDefaultWebXmlFragment(webXmlParser));
WebXml webXml = createWebXml();
InputSource contextWebXml = getContextWebXmlSource();// Parse context level web.xml
if (!webXmlParser.parseWebXml(contextWebXml, webXml, false)) {
ok = false;
}...
// Step 1. Identify all the JARs packaged with the application and those
// provided by the container. If any of the application JARs have a
// web-fragment.xml it will be parsed at this point. web-fragment.xml
// files are ignored for container provided JARs.
Map<String,WebXml> fragments = processJarsForWebFragments(webXml, webXmlParser);
// Step 2. Order the fragments.
Set<WebXml> orderedFragments = null;
orderedFragments =
WebXml.orderWebFragments(webXml, fragments, sContext);
// Step 3. Look for ServletContainerInitializer implementations
if (ok) {
processServletContainerInitializers();
}
if (!webXml.isMetadataComplete() || typeInitializerMap.size() > 0) {
// Steps 4 & 5.
processClasses(webXml, orderedFragments);//没有配置时,里面有处理注解式(servelt3)的
}
if (!webXml.isMetadataComplete()) {
// Step 6. Merge web-fragment.xml files into the main web.xml
// file.
if (ok) {
ok = webXml.merge(orderedFragments);
}
// Step 7. Apply global defaults
// Have to merge defaults before JSP conversion since defaults
// provide JSP servlet definition.
webXml.merge(defaults);
// Step 8. Convert explicitly mentioned jsps to servlets
if (ok) {
convertJsps(webXml);
}
// Step 9. Apply merged web.xml to Context
if (ok) {
configureContext(webXml);
}
...}
processAnnotationsWebResource() {...
processAnnotationsStream(is, fragment, handlesTypesOnly, javaClassCache);
...}
processAnnotationsStream{...
ClassParser parser = new ClassParser(is);//解析,并没有立刻加载到jvm,使用的时候在加载
JavaClass clazz = parser.parse();
checkHandlesTypes(clazz, javaClassCache);
if (handlesTypesOnly) {
return;
}
processClass(fragment, clazz);
...}
configureContext(){...
for (FilterMap filterMap : webxml.getFilterMappings()) {
context.addFilterMap(filterMap);
}
context.setJspConfigDescriptor(webxml.getJspConfigDescriptor());
for (String listener : webxml.getListeners()) {
context.addApplicationListener(listener);
}...
context.addChild(wrapper);//line 1380 添加了wrapper(servlet)
...}
StandardContext.startInternal(){...
// Start our child containers, if not already started
for (Container child : findChildren()) {
if (!child.getState().isAvailable()) {
child.start();
}
}
...}
后续severlet的加载,优先级 warpper load方法等:
容器组件启动会触发lisener监听器从而知道容器中发生了变化(如:热部署)。