类加载器:每个Class对象都保留着加载自己的类加载器的引用,可以通过Class对象的getClassLoader方法来获得其引用。ClassLoader通过loadClass方法来加载这个类。
按照类加载器,首先应该加载父类,也就是通常所说的父类优先的原则,但是在web容器中加载顺序有所不同。
通过查找资料找到这样的叙述:
对于运行在 Java EE容器中的 Web 应用来说,类加载器的实现方式与一般的 Java 应用有所不同。不同的 Web 容器的实现方式也会有所不同。以 Apache Tomcat 来说,每个 Web 应用都有一个对应的类加载器实例。该类加载器也使用代理模式,所不同的是它是首先尝试去加载某个类,如果找不到再代理给父类加载器。这与一般类加载器的顺序是相反的。这是 Java Servlet 规范中的推荐做法,其目的是使得 Web 应用自己的类的优先级高于 Web 容器提供的类。这种代理模式的一个例外是:Java 核心库的类是不在查找范围之内的。这也是为了保证 Java 核心库的类型安全。
绝大多数情况下,Web 应用的开发人员不需要考虑与类加载器相关的细节。下面给出几条简单的原则:
每个 Web 应用自己的 Java 类文件和使用的库的 jar 包,分别放在 WEB-INF/classes和 WEB-INF/lib目录下面。
多个应用共享的 Java 类文件和 jar 包,分别放在 Web 容器指定的由所有 Web 应用共享的目录下面。
当出现找不到类的错误时,检查当前类的类加载器和当前线程的上下文类加载器是否正确。
于是对于一个普通web项目,properties文件可以放在src目录下,经过编译器编译之后目录变为WEB-INF/classes目录.
java web项目部署到tomcat后根目录如下
| --META-INF
--WEB-INF -->包含 classess、lib文件夹和web.xml文件,
index.jsp
classes包含编译后的.class文件和配置文件
路径变化后,只能通过类加载器来获得文件路径,否则无法加载。
serlvet中加载配置文件,此时ServletContext为根目录
public void init() throws ServletException { //web容器为根目录 InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/info.properties"); Properties pro = new Properties(); try { pro.load(in); } catch (IOException e) { log.error("读取info.properties失败"+e.getMessage()); } super.init(); }
如果在其它类可以使用getClass().getClassLoader().getResourceAsStream(filePath) ,此时classes目录为根目录:classPath
InputStream is = null; Properties pro = new Properties(); is = getClass().getClassLoader().getResourceAsStream("/info.properties"); //无论要查找的资源前面是否带'/' 都会从classpath的根路径下查找。 pro.load(is); Enumeration e = pro.propertyNames(); while (e.hasMoreElements()) { String key = (String) e.nextElement(); String value = (String) pro.get(key); proMap.put(key, value); } is.close();
注意:getClass().getClassLoader().getResourceAsStream() 与 getClass().getResourceAsStream() 区别 参考stackoverflow:link1 link2
Class.getResourceAsStream() 会指定要加载的资源路径与当前类所在包的路径一致。
例如你写了一个MyTest类在包com.test.mycode 下,那么MyTest.class.getResourceAsStream("name") 会在com.test.mycode包下查找相应的资源。
如果这个name是以 '/' 开头的,那么就会从classpath的根路径下开始查找。
参考:从读取properties文件说开去,浅谈web容器中类加载器 关于servlet中properties配置文件的存放位置 JAVA 笔记xx.getClass().getClassLoader().getResourceAsStream()