这里所说的组件可以将其理解为我们最开始分析 server.xml 时 xml 文件里的各个节点,父子关系也即 xml 文件里的父子节点。浏览下 LifecycleBase 的子类就会发现节点的实现类都是这个类的子类(记住这点,后面会提到)。
同样分析 start 方法:
1 /**
2 * {@inheritDoc}
3 */
4 @Override
5 public final synchronized void start() throws LifecycleException {
6
7 if (LifecycleState.STARTING_PREP.equals(state) ||
8 LifecycleState.STARTING.equals(state) ||
9 LifecycleState.STARTED.equals(state)) {
10
11 if (log.isDebugEnabled()) {
12 Exception e = new LifecycleException();
13 log.debug(sm.getString("lifecycleBase.alreadyStarted",
14 toString()), e);
15 } else if (log.isInfoEnabled()) {
16 log.info(sm.getString("lifecycleBase.alreadyStarted",
17 toString()));
18 }
19
20 return;
21 }
22
23 if (state.equals(LifecycleState.NEW)) {
24 init();
25 } else if (state.equals(LifecycleState.FAILED)){
26 stop();
27 } else if (!state.equals(LifecycleState.INITIALIZED) &&
28 !state.equals(LifecycleState.STOPPED)) {
29 invalidTransition(Lifecycle.BEFORE_START_EVENT);
30 }
31
32 setStateInternal(LifecycleState.STARTING_PREP, null, false);
33
34 try {
35 startInternal();
36 } catch (Throwable t) {
37 ExceptionUtils.handleThrowable(t);
38 setStateInternal(LifecycleState.FAILED, null, false);
39 throw new LifecycleException(
40 sm.getString("lifecycleBase.startFail",toString()), t);
41 }
42
43 if (state.equals(LifecycleState.FAILED) ||
44 state.equals(LifecycleState.MUST_STOP)) {
45 stop();
46 } else {
47 // Shouldn't be necessary but acts as a check that sub-classes are
48 // doing what they are supposed to.
49 if (!state.equals(LifecycleState.STARTING)) {
50 invalidTransition(Lifecycle.AFTER_START_EVENT);
51 }
52
53 setStateInternal(LifecycleState.STARTED, null, false);
54 }
55 }
56
57
58 /**
59 * Sub-classes must ensure that the state is changed to
60 * {@link LifecycleState#STARTING} during the execution of this method.
61 * Changing state will trigger the {@link Lifecycle#START_EVENT} event.
62 *
63 * If a component fails to start it may either throw a
64 * {@link LifecycleException} which will cause it's parent to fail to start
65 * or it can place itself in the error state in which case {@link #stop()}
66 * will be called on the failed component but the parent component will
67 * continue to start normally.
68 *
69 * @throws LifecycleException
70 */
71 protected abstract void startInternal() throws LifecycleException;
1 /**
2 * Invoke a pre-startup initialization. This is used to allow connectors
3 * to bind to restricted ports under Unix operating environments.
4 */
5 @Override
6 protected void initInternal() throws LifecycleException {
7
8 super.initInternal();
9
10 // Register global String cache
11 // Note although the cache is global, if there are multiple Servers
12 // present in the JVM (may happen when embedding) then the same cache
13 // will be registered under multiple names
14 onameStringCache = register(new StringCache(), "type=StringCache");
15
16 // Register the MBeanFactory
17 MBeanFactory factory = new MBeanFactory();
18 factory.setContainer(this);
19 onameMBeanFactory = register(factory, "type=MBeanFactory");
20
21 // Register the naming resources
22 globalNamingResources.init();
23
24 // Populate the extension validator with JARs from common and shared
25 // class loaders
26 if (getCatalina() != null) {
27 ClassLoader cl = getCatalina().getParentClassLoader();
28 // Walk the class loader hierarchy. Stop at the system class loader.
29 // This will add the shared (if present) and common class loaders
30 while (cl != null && cl != ClassLoader.getSystemClassLoader()) {
31 if (cl instanceof URLClassLoader) {
32 URL[] urls = ((URLClassLoader) cl).getURLs();
33 for (URL url : urls) {
34 if (url.getProtocol().equals("file")) {
35 try {
36 File f = new File (url.toURI());
37 if (f.isFile() &&
38 f.getName().endsWith(".jar")) {
39 ExtensionValidator.addSystemResource(f);
40 }
41 } catch (URISyntaxException e) {
42 // Ignore
43 } catch (IOException e) {
44 // Ignore
45 }
46 }
47 }
48 }
49 cl = cl.getParent();
50 }
51 }
52 // Initialize our defined Services
53 for (int i = 0; i < services.length; i++) {
54 services[i].init();
55 }
56 }
init 方法里面做了好几件事情,牵涉的话题比较多,这里重点关注最后第 53 到 55 行的代码,这里将循环调用 Server 类里内置的 Service 数组的 init 方法。
startInternal 方法:
1 /**
2 * Start nested components ({@link Service}s) and implement the requirements
3 * of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
4 *
5 * @exception LifecycleException if this component detects a fatal error
6 * that prevents this component from being used
7 */
8 @Override
9 protected void startInternal() throws LifecycleException {
10
11 fireLifecycleEvent(CONFIGURE_START_EVENT, null);
12 setState(LifecycleState.STARTING);
13
14 globalNamingResources.start();
15
16 // Start our defined Services
17 synchronized (services) {
18 for (int i = 0; i < services.length; i++) {
19 services[i].start();
20 }
21 }
22 }
重点关注第 17 到 21 行,同上一段所分析的代码类似,将循环调用 Sever 类里内置的 Service 数组的 start 方法。