首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

浅析Tomcat之Bootstrap种

2013-10-16 
浅析Tomcat之Bootstrap类Tomcat的启动类是Bootstrap,它承担着管理Catalina的责任.看其main方法可以知道它

浅析Tomcat之Bootstrap类

Tomcat的启动类是Bootstrap,它承担着管理Catalina的责任.看其main方法可以知道它首先是实例化一个Bootstrap实例,这是一个主线程.该实例创建后立即进行初始化,次调用是一个很复杂的过程.它包含了Tomcat的很多初始化工作,接着是把该实例赋值给静态变量daemon.然后才是执行相应的启动或者停止命令.

?

首先,看看Bootstrap的init方法,代码如下:

setCatalinaHome();setCatalinaBase();initClassLoaders();Thread.currentThread().setContextClassLoader(catalinaLoader);SecurityClassLoad.securityClassLoad(catalinaLoader);// Load our startup class and call its process() methodif (log.isDebugEnabled())log.debug("Loading startup class");Class<?> startupClass =catalinaLoader.loadClass("org.apache.catalina.startup.Catalina");Object startupInstance = startupClass.newInstance();// Set the shared extensions class loaderif (log.isDebugEnabled())log.debug("Setting startup class properties");String methodName = "setParentClassLoader";Class<?> paramTypes[] = new Class[1];paramTypes[0] = Class.forName("java.lang.ClassLoader");Object paramValues[] = new Object[1];paramValues[0] = sharedLoader;Method method =startupInstance.getClass().getMethod(methodName, paramTypes);method.invoke(startupInstance, paramValues);catalinaDaemon = startupInstance;

setCatalinaHome方法是设置系统变量catalina.home.如果系统中没有设置这个变量的话默认是当前的工作目录.setCatalinaBase是设置变量catalina.base,与setCatalinaHome方法类似.initClassLoaders是初始化类加载器.这些类加载器是通过配置文件来进行配置的,本文稍后进行解析.接着是实例化org.apache.catalina.startup.Catalina这个类,并设置它的类加载器.这个类才是Tomcat提供服务的地方.Bootstrap不过是为了外部对Catalina进行控制的媒介.我们可以看到Bootstrap执行start或者stop等方法都是对catalinaDaemon进行操作的,也就是控制catalina的启动或者停止.

commonLoader = createClassLoader("common", null);if( commonLoader == null ) {// no config file, default to this loader - we might be in a 'single' env.commonLoader=this.getClass().getClassLoader();}catalinaLoader = createClassLoader("server", commonLoader);sharedLoader = createClassLoader("shared", commonLoader);

?上述代码是initClassLoaders的主体它是调用createClassLoader来创建ClassLoader的.其主要代码如下

String value = CatalinaProperties.getProperty(name + ".loader");if ((value == null) || (value.equals("")))return parent;value = replace(value);List<Repository> repositories = new ArrayList<Repository>();StringTokenizer tokenizer = new StringTokenizer(value, ",");while (tokenizer.hasMoreElements()) {String repository = tokenizer.nextToken().trim();if (repository.length() == 0) {continue;}// Check for a JAR URL repositorytry {@SuppressWarnings("unused")URL url = new URL(repository);repositories.add(new Repository(repository, RepositoryType.URL));continue;} catch (MalformedURLException e) {// Ignore}// Local repositoryif (repository.endsWith("*.jar")) {repository = repository.substring(0, repository.length() - "*.jar".length());repositories.add(new Repository(repository, RepositoryType.GLOB));} else if (repository.endsWith(".jar")) {repositories.add(new Repository(repository, RepositoryType.JAR));} else {repositories.add(new Repository(repository, RepositoryType.DIR));}}ClassLoader classLoader = ClassLoaderFactory.createClassLoader(repositories, parent);// Retrieving MBean serverMBeanServer mBeanServer = null;if (MBeanServerFactory.findMBeanServer(null).size() > 0) {mBeanServer = MBeanServerFactory.findMBeanServer(null).get(0);} else {mBeanServer = ManagementFactory.getPlatformMBeanServer();}// Register the server classloaderObjectName objectName =new ObjectName("Catalina:type=ServerClassLoader,name=" + name);mBeanServer.registerMBean(classLoader, objectName);return classLoader;

?CatalinaProperties对应着Tomcat目录下的catalina.propertis.默认的配置有common.loader=${catalina.base}/lib,${catalina.base}/lib/*.jar,${catalina.home}/lib,${catalina.home}/lib/*.jar也就是配置了commonClassLoader的类路径.这里就指定了Catalina所能load的类的路径.因为init在实例化Catalina实例后调用了setParentClassLoader把initClassLoaders中初始化好的自定义ClassLoader类设置给Catalina.

经过上述步骤后Bootstrap基本上已经初始化好,接下来就是命令行中传入的是何种命令,执行相应的方法.

String command = "start";if (args.length > 0) {command = args[args.length - 1];}if (command.equals("startd")) {args[args.length - 1] = "start";daemon.load(args);daemon.start();} else if (command.equals("stopd")) {args[args.length - 1] = "stop";daemon.stop();} else if (command.equals("start")) {daemon.setAwait(true);daemon.load(args);daemon.start();} else if (command.equals("stop")) {daemon.stopServer(args);} else if (command.equals("configtest")) {daemon.load(args);if (null==daemon.getServer()) {System.exit(1);}System.exit(0);} else {log.warn("Bootstrap: command "" + command + "" does not exist.");}

?默认执行的是start命令,也就是调用了Bootstrap的start方法.该方法是启动Tomcat连接器和容器.在以后的博文中进行解读.

?

?

首发于泛泛之辈 -?http://www.lihongkun.com/archives/84

热点排行