- 浏览: 332308 次
- 性别:
- 来自: 火星
文章分类
最新评论
-
zhanggang807:
这个ibatis 还真是不好用啊。楼主解决了我看文档也没解决的 ...
IBATIS Iterate用法 初探 -
lijunwyf41:
不错 SqlMapClientTemplate sqlMa ...
IBATIS batch用法探究 -
huyuancai1010:
.
struts2 常量配置详解 -
jd2bs:
2楼肯定是people.xsd格式错了
spring schema 扩展 -
xiaokang1582830:
遇到同样的问题,请教如何解决的java.io.NotSeria ...
ibatis 延迟加载 探究
tomcat 为了做到每个host中都能加载各种不同的WEB应用而不相互影响,采用的类加载机制有所特别:
加载WEB应用中我们自己写的类的顺序也是按照图中 标示的1243顺序所示。
把WebAppClassLoader.java的loadClass方法贴出来瞧瞧:
public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { if (log.isDebugEnabled()) log.debug("loadClass(" + name + ", " + resolve + ")"); Class clazz = null; // Log access to stopped classloader if (!started) { try { throw new IllegalStateException(); } catch (IllegalStateException e) { log.info(sm.getString("webappClassLoader.stopped", name), e); } } // (0) Check our previously loaded local class cache.从先前已经加载的本地 cache中查找该类 clazz = findLoadedClass0(name); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Returning class from cache"); if (resolve) resolveClass(clazz); return (clazz); } // (0.1) Check our previously loaded class cache .从先前已经加载cache中查找该类 clazz = findLoadedClass(name); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Returning class from cache"); if (resolve) resolveClass(clazz); return (clazz); } // (0.2) Try loading the class with the system class loader, to prevent // the webapp from overriding J2SE classes // 尝试从system class loader中加载,保护j2se 的核心类。 try { clazz = system.loadClass(name); if (clazz != null) { if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { // Ignore } // (0.5) Permission to access this class when using a SecurityManager if (securityManager != null) { int i = name.lastIndexOf('.'); if (i >= 0) { try { securityManager.checkPackageAccess(name.substring(0,i)); } catch (SecurityException se) { String error = "Security Violation, attempt to use " + "Restricted Class: " + name; log.info(error, se); throw new ClassNotFoundException(error, se); } } } boolean delegateLoad = delegate || filter(name); // (1) Delegate to our parent if requested // 如果delegate被设置为true的话委托给双亲加载 if (delegateLoad) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader1 " + parent); ClassLoader loader = parent; if (loader == null) loader = system; try { clazz = loader.loadClass(name); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Loading class from parent"); if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { ; } } // (2)从WEB-INF/lib ,WEB-INF/classes加载类 if (log.isDebugEnabled()) log.debug(" Searching local repositories"); try { clazz = findClass(name); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Loading class from local repository"); if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { ; } // (3) Delegate to parent unconditionally // 如果本地找不到需要加载的类,则还是委托双亲去加载该类 if (!delegateLoad) { if (log.isDebugEnabled()) log.debug(" Delegating to parent classloader at end: " + parent); ClassLoader loader = parent; if (loader == null) loader = system; try { clazz = loader.loadClass(name); if (clazz != null) { if (log.isDebugEnabled()) log.debug(" Loading class from parent"); if (resolve) resolveClass(clazz); return (clazz); } } catch (ClassNotFoundException e) { ; } } throw new ClassNotFoundException(name); }
那么在哪里用到了WebAppClassLoader呢,见下面的代码,代码贴的比较长。但是比较重点的:
StandardWrapper.java
/** * Load and initialize an instance of this servlet, if there is not already at least one initialized instance. This * can be used, for example, to load servlets that are marked in the deployment descriptor to be loaded at server * startup time. */ public synchronized Servlet loadServlet() throws ServletException { // Nothing to do if we already have an instance or an instance pool // 初始化servlet的时候,如果发现已经初始化完毕,则不再初始化 if (!singleThreadModel && (instance != null)) return instance; // 把标准输出重定向 PrintStream out = System.out; if (swallowOutput) { SystemLogHandler.startCapture(); } Servlet servlet; try { long t1 = System.currentTimeMillis(); // If this "servlet" is really a JSP file, get the right class. // HOLD YOUR NOSE - this is a kludge that avoids having to do special // case Catalina-specific code in Jasper - it also requires that the // servlet path be replaced by the <jsp-file> element content in // order to be completely effective /** * <pre> * 以下代码为了使类似这样的配置 * <servlet> * <servlet-name>Test</servlet-name> * <jsp-file>/TestPage.jsp</jsp-file> * </servlet> * 其中<jsp-file>是用来代替<servlet-class>的 * </pre> */ String actualClass = servletClass; if ((actualClass == null) && (jspFile != null)) { Wrapper jspWrapper = (Wrapper) ((Context) getParent()).findChild(Constants.JSP_SERVLET_NAME); if (jspWrapper != null) { actualClass = jspWrapper.getServletClass(); // Merge init parameters String paramNames[] = jspWrapper.findInitParameters(); for (int i = 0; i < paramNames.length; i++) { if (parameters.get(paramNames[i]) == null) { parameters.put(paramNames[i], jspWrapper.findInitParameter(paramNames[i])); } } } } // Complain if no servlet class has been specified // 如果配置文件中<servlet-class>没有指定的话,抛出抱怨 if (actualClass == null) { unavailable(null); throw new ServletException(sm.getString("standardWrapper.notClass", getName())); } // Acquire an instance of the class loader to be used // 获取一个CLASS LOADER来搞,一般获得的是WebAppClassLoader Loader loader = getLoader(); if (loader == null) { unavailable(null); throw new ServletException(sm.getString("standardWrapper.missingLoader", getName())); } ClassLoader classLoader = loader.getClassLoader(); // Special case class loader for a container provided servlet if (isContainerProvidedServlet(actualClass) && !((Context) getParent()).getPrivileged()) { // If it is a priviledged context - using its own // class loader will work, since it's a child of the container // loader classLoader = this.getClass().getClassLoader(); } // Load the specified servlet class from the appropriate class loader Class classClass = null; try { if (SecurityUtil.isPackageProtectionEnabled()) { final ClassLoader fclassLoader = classLoader; final String factualClass = actualClass; try { classClass = (Class) AccessController.doPrivileged(new PrivilegedExceptionAction() { public Object run() throws Exception { if (fclassLoader != null) { return fclassLoader.loadClass(factualClass); } else { return Class.forName(factualClass); } } }); } catch (PrivilegedActionException pax) { Exception ex = pax.getException(); if (ex instanceof ClassNotFoundException) { throw (ClassNotFoundException) ex; } else { getServletContext().log("Error loading " + fclassLoader + " " + factualClass, ex); } } } else { if (classLoader != null) { // 使用WebAppClassLoader加载实际的类 classClass = classLoader.loadClass(actualClass); } else { classClass = Class.forName(actualClass); } } } catch (ClassNotFoundException e) { unavailable(null); getServletContext().log("Error loading " + classLoader + " " + actualClass, e); throw new ServletException(sm.getString("standardWrapper.missingClass", actualClass), e); } if (classClass == null) { unavailable(null); throw new ServletException(sm.getString("standardWrapper.missingClass", actualClass)); } // Instantiate and initialize an instance of the servlet class itself try { // 创建一个Servlet实例 servlet = (Servlet) classClass.newInstance(); // Annotation processing if (!((Context) getParent()).getIgnoreAnnotations()) { if (getParent() instanceof StandardContext) { ((StandardContext) getParent()).getAnnotationProcessor().processAnnotations(servlet); ((StandardContext) getParent()).getAnnotationProcessor().postConstruct(servlet); } } } catch (ClassCastException e) { unavailable(null); // Restore the context ClassLoader throw new ServletException(sm.getString("standardWrapper.notServlet", actualClass), e); } catch (Throwable e) { unavailable(null); // Added extra log statement for Bugzilla 36630: // http://issues.apache.org/bugzilla/show_bug.cgi?id=36630 if (log.isDebugEnabled()) { log.debug(sm.getString("standardWrapper.instantiate", actualClass), e); } // Restore the context ClassLoader throw new ServletException(sm.getString("standardWrapper.instantiate", actualClass), e); } // Check if loading the servlet in this web application should be // allowed if (!isServletAllowed(servlet)) { throw new SecurityException(sm.getString("standardWrapper.privilegedServlet", actualClass)); } // Special handling for ContainerServlet instances if ((servlet instanceof ContainerServlet) && (isContainerProvidedServlet(actualClass) || ((Context) getParent()).getPrivileged())) { ((ContainerServlet) servlet).setWrapper(this); } classLoadTime = (int) (System.currentTimeMillis() - t1); // Call the initialization method of this servlet try { // 触发servlet的beforeInit事件 instanceSupport.fireInstanceEvent(InstanceEvent.BEFORE_INIT_EVENT, servlet); if (Globals.IS_SECURITY_ENABLED) { Object[] args = new Object[] { ((ServletConfig) facade) }; SecurityUtil.doAsPrivilege("init", servlet, classType, args); args = null; } else { // 触发servlet初始化操作 servlet.init(facade); } // Invoke jspInit on JSP pages if ((loadOnStartup >= 0) && (jspFile != null)) { // Invoking jspInit DummyRequest req = new DummyRequest(); req.setServletPath(jspFile); req.setQueryString(Constants.PRECOMPILE + "=true"); DummyResponse res = new DummyResponse(); if (Globals.IS_SECURITY_ENABLED) { Object[] args = new Object[] { req, res }; SecurityUtil.doAsPrivilege("service", servlet, classTypeUsedInService, args); args = null; } else { servlet.service(req, res); } } // 触发afterInit初始化操作 instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT, servlet); } catch (UnavailableException f) { instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT, servlet, f); unavailable(f); throw f; } catch (ServletException f) { instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT, servlet, f); // If the servlet wanted to be unavailable it would have // said so, so do not call unavailable(null). throw f; } catch (Throwable f) { getServletContext().log("StandardWrapper.Throwable", f); instanceSupport.fireInstanceEvent(InstanceEvent.AFTER_INIT_EVENT, servlet, f); // If the servlet wanted to be unavailable it would have // said so, so do not call unavailable(null). throw new ServletException(sm.getString("standardWrapper.initException", getName()), f); } // Register our newly initialized instance // singleTheadModel纯粹没用的东西,不用考虑了 singleThreadModel = servlet instanceof SingleThreadModel; if (singleThreadModel) { if (instancePool == null) instancePool = new Stack(); } fireContainerEvent("load", this); loadTime = System.currentTimeMillis() - t1; } finally { if (swallowOutput) { String log = SystemLogHandler.stopCapture(); if (log != null && log.length() > 0) { if (getServletContext() != null) { getServletContext().log(log); } else { out.println(log); } } } } return servlet; }
发表评论
-
tomcat engine,host,context的管道处理——pipeline
2010-05-20 00:08 1606所有实现了Pipeline接口的都可以配置自己的valve。进 ... -
tomcat 生命周期,和事件管理—— lifeCycle & event
2010-05-19 00:26 1521针对各种容器的生命周期管理: 针对 RequestDisp ... -
tomcat 对静态资源的处理 —— Default Servlet
2010-05-18 19:03 13180首先所有的请求进入tomcat,都会流经servlet,如果没 ... -
tomcat源码分析之一《架构》
2010-05-18 10:14 3650首先感谢我的好朋友罗兵,此文摘自他的文章 tomcat源码 ... -
tomcat session——对session的支持
2010-05-13 23:40 2583一,tomcat 如何支持session 首先来看下$cat ... -
tomcat HTTP处理—— Request的生命历程和相应Connector配置解析
2010-05-12 23:02 10432Request的生命历程,可以参见常量类org.apache. ... -
tomcat分配请求之——请求如何流程Connection
2010-05-09 23:18 2307首先摘自我的好友。傻博语录:人生就是悲剧 上次说 ... -
tomcat 分配请求之——socket获取请求
2010-05-07 17:58 1915首先,安装,调试tomcat的源码: http://smi ...
相关推荐
在Tomcat服务器中,类的加载方式与JVM的标准类加载机制有所不同。Tomcat采用了更加细粒度的类加载策略,以支持更复杂的Web应用程序部署。 **1. Tomcat中的类加载器** 当Tomcat启动时,会创建几种类加载器: - **...
Tomcat的类加载机制采用层次化的类加载器模型,确保不同级别的类加载不会互相干扰,具体包括以下几个级别: 1. **Bootstrap ClassLoader**: 负责加载Java核心类库(位于`$JAVA_HOME/jre/lib`或`$JAVA_HOME/jre/lib/...
在Tomcat服务器中,类的加载机制有所不同,主要包括以下几种类型的类加载器: - **Bootstrap ClassLoader**:加载JVM启动所需的核心类和标准扩展类。 - **System ClassLoader**:加载Tomcat启动所需的类文件,如`...
Tomcat通过`org.apache.naming.ContextBindings`类实现了JNDI中的`ContextBinding`机制。`ContextBindings`类负责维护一个`java.util.Hashtable`,用于存储和管理ClassLoader级别的上下文绑定信息。这允许每个应用或...
8. **ClassLoader:** ClassLoader是类加载器,它负责加载应用程序的类文件,Tomcat采用了层次化的ClassLoader机制,确保了类的隔离性,避免了类加载冲突。 #### Tomcat的安装与配置 - 在Windows平台上安装Tomcat...
Tomcat使用自定义的ClassLoader来加载Web应用的类。每个Web应用都有自己的ClassLoader,这样可以避免不同应用之间的类冲突。ClassLoader还会处理应用的依赖管理,加载JAR文件中的类。 5. **StandardServer和...
- **Classloader**:包括启动类加载器、扩展类加载器、应用类加载器等,采用双亲委派机制。 #### Java内存模型与并发应用 - **指令重排序**:为了优化性能,编译器和处理器可能会重新排列指令执行顺序。 - **内存...
- **定义**: 负责加载应用程序类路径中的类。 **7.25 全盘负责委托机制** - **说明**: 类加载器之间的层次结构及委托关系。 #### XML 处理技术 **7.26 Tip:DTD 的语法细节** - **内容**: - 元素定义 - 属性定义...
- 动态加载并执行解密后的类文件,实现远程代码执行。 3. **HTTP请求示例**:攻击者通过发送如下POST请求将恶意代码写入指定位置: ``` POST /WebReport/ReportServer? op=svginit&cmd=design_save_svg&...
3.2.2 类装载器ClassLoader 3.2.3 Java反射机制 3.3 资源访问利器 3.3.1 资源抽象接口 3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 ...
3.2.2 类装载器ClassLoader 3.2.3 Java反射机制 3.3 资源访问利器 3.3.1 资源抽象接口 3.3.2 资源加载 3.4 BeanFactory和ApplicationContext 3.4.1 BeanFactory介绍 3.4.2 ApplicationContext介绍 3.4.3 父子容器 ...