web容器中的类加载器加载文件

类加载器:每个Class对象都保留着加载自己的类加载器的引用,可以通过Class对象的getClassLoader方法来获得其引用。ClassLoader通过loadClass方法来加载这个类。

 

按照类加载器,首先应该加载父类,也就是通常所说的父类优先的原则,但是在web容器中加载顺序有所不同。

 
web容器中的类加载器加载文件_第1张图片
 

 

 

通过查找资料找到这样的叙述:

 

对于运行在 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()

 

你可能感兴趣的:(java)