- Tomcat自定义载入器(一般为WebappClassLoader)本地缓存及ClassLoader缓存
- Bootstrap class loader载入(在其安全目录内)
- Extension class loader载入(在其安全目录内,比如这里为:$JAVA_HOME/jre/lib/ext/*.jar )
- System class loader (在其安全目录内,比如这里为:CLASSPATH/)
注意:以上要优先主要是基于安全,避免类似自定义java.lang.Object优先于JDK的java.lang.Object被加载 - /WEB-INF/classes/*.class
- /WEB-INF/lib/*.jar 这里面按包名的字典顺序去加载
- $CATALINA_HOME/common/classes
- $CATALINA_HOME/common/endorsed/*.jar
- $CATALINA_HOME/common/i18n/*.jar
- $CATALINA_HOME/common/lib/*.jar
- $CATALINA_BASE/shared/classes
- $CATALINA_BASE/shared/lib/*.jar
由于类加载器对于同名(包括包路径)的类只会加载一次所以我们可以采取些手段去改变一个类的行为
比如我们想做这么一件事 在ibatis 启动的时候我们需要检查一下sqlmap 中是不是存在注入的风险
- 首先我们可以重写com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate 的 addMappedStatement方法 用正则去匹配可能存在注入风险的sql如果存在则抛异常。当然这只是最原始最野蛮的一个办法
- 其次我们可以将这个类单独放在一个jar包里 为了达到优先加载的目的 我们可以将jar包的名字以 _ 开头 这样就可先于 ibatis jar包里面原来的类加载
- 同样是这样的jar我们可以放到更前一步 比如$JAVA_HOME/jre/lib/ext 目录下
- 甚至我们可以使用java agent 通过jdk 的 Instrumentation 配合asm完成,当然这个就要求开发人员对 class 文件结构有一定的了解