ClassLoader (CurrentClassLoader, ParentClassLoader 및 ContextClassLoader) 에 대해 다시 이야기 합 니 다.
내 생각 은 전체 응용 서버 가 다음 과 같은 xml 로 설정 되 어 있다 는 것 이다.
<App name="Server">
<App name="s1" path="...">
<App name="s1_1" path="..." />
</App>
<App name="s2" path="...">
<App name="s2_1" path="..." />
</App>
</App>
모든 앱 은 하나의 애플 리 케 이 션 이자 용기 입 니 다. 맨 위 에 있 는 앱 은 바로 이 애플 리 케 이 션 서버 자체 입 니 다.응용 서버 자체 와 응용 은 완전히 평등 하 며, 모든 외부 용기 (응용) 는 내부 의 모든 용기 (응용) 의 생명 주 기 를 재 귀적 으로 책임 집 니 다.
path 에 대응 하 는 디 렉 터 리 아래 에 두 개의 하위 디 렉 터 리 가 있어 야 합 니 다. 각각 lib 와 classes 입 니 다. 이 두 디 렉 터 리 는 이 응용 프로그램의 classpath 를 정의 합 니 다. 응용 사이 에 다른 응용 프로그램의 classpath 가 보이 지 않 고 내부 응용 만 외층 을 볼 수 있 습 니 다.
문 제 는 이 스 레 드 에서 실행 되 는 코드 를 지정 한 ClassLoader 에서 클래스 의 정 의 를 찾 을 수 있 도록 스 레 드 를 시작 하 는 방법 입 니 다.
이 문 제 를 해결 하기 위해 서 우 리 는 코드 를 좀 보 았 다.우 리 는 다음 세 가지 방법 으로 하나의 경로 에서 URLClassLoader 를 생 성 합 니 다.
private static ClassLoader createClassLoader(String path) throws Exception {
List<File> jarList = new ArrayList<File>();
getClassPath(jarList, new Filter(), new File(path, "lib"));
List<URL> urlList = new ArrayList<URL>();
urlList.add(new URL("file:///" + path + "/classes/"));
for (int i = 0; i < jarList.size(); ++i) {
urlList.add(new URL("file:///"
+ ((File) jarList.get(i)).getCanonicalPath()));
}
return new URLClassLoader((URL[]) urlList.toArray(new URL[0]), Thread
.currentThread().getContextClassLoader());
}
private static void getClassPath(List<File> list, Filter filter, File f) {
if (f.exists() && f.isDirectory()) {
File[] ss = f.listFiles(filter);
for (int i = 0; i < ss.length; ++i) {
if (ss[i].isFile()) {
list.add(ss[i]);
} else if (ss[i].isDirectory()) {
getClassPath(list, filter, ss[i]);
}
}
}
}
private static class Filter implements FilenameFilter {
public boolean accept(File dir, String name) {
File f = new File(dir, name);
boolean isDir = f.isDirectory();
boolean isFile = f.isFile();
boolean isJar = name.toLowerCase().endsWith(".jar");
boolean isZip = name.toLowerCase().endsWith(".zip");
return (isFile && (isJar || isZip)) || isDir;
}
}
createClassLoader 방법 은 path 디 렉 터 리 에 있 는 lib 와 classes 두 디 렉 터 리 에서 클래스 의 정 의 를 찾 고 해당 하 는 URLClassLoader 를 되 돌려 줍 니 다.이것 이 첫걸음 이다.
다음은 이 스 레 드 에서 실행 중인 코드 를 createClassLoader 가 돌아 오 는 ClassLoader 의 classpath 에서 클래스 정 의 를 찾 고 새 스 레 드 (App) 의 ParentClassLoader 를 시작 하 는 스 레 드 로 설정 하고 새 스 레 드 (App) 를 설정 해 야 합 니 다.의 ContextClassLoader 를 createClassLoader 로 되 돌려 주 는 ClassLoader 입 니 다.우 리 는 먼저 새 스 레 드 (App) 의 코드 를 봅 니 다.
package test;
public class T extends Thread {
public void run() {
System.out.println("App context: "
+ Thread.currentThread().getContextClassLoader());
System.out.println("App parent: "
+ this.getClass().getClassLoader().getParent());
System.out.println("App current: " + this.getClass().getClassLoader());
}
}
마지막 으로 코드 로 이 테스트 프로그램 을 시작 합 니 다:
public static void main(String[] args) throws Exception {
ClassLoader appClassLoader = createClassLoader("D:/P/eclipse/workspace/TestApp");
Class c = appClassLoader.loadClass("test.T");
Object t = c.newInstance();
Method setContextClassLoader = c.getMethod("setContextClassLoader",
new Class[] { ClassLoader.class });
setContextClassLoader.invoke(t, appClassLoader);
Method start = c.getMethod("start", new Class[] {});
start.invoke(t, new Object[] {});
System.out.println("Main context: "
+ Thread.currentThread().getContextClassLoader());
System.out.println("Main current: " + Test.class.getClassLoader());
System.out.println("Main parent: "
+ Test.class.getClassLoader().getParent());
System.out.println("App ClassLoader: " + appClassLoader);
System.out.println("Systen ClassLoader: "
+ ClassLoader.getSystemClassLoader());
}
출력 결 과 는:
Main context: sun.misc.Launcher$AppClassLoader@11b86e7
Main current: sun.misc.Launcher$AppClassLoader@11b86e7
Main parent: sun.misc.Launcher$ExtClassLoader@35ce36
App ClassLoader: java.net.URLClassLoader@addbf1
Systen ClassLoader: sun.misc.Launcher$AppClassLoader@11b86e7
App context: java.net.URLClassLoader@addbf1
App parent: sun.misc.Launcher$AppClassLoader@11b86e7
App current: java.net.URLClassLoader@addbf1
메 인 은 바깥쪽 용 기 를, 앱 은 안쪽 용 기 를 대표 한다.이때 앱 의 ContextClassLoader 와 CurrentClassLoader 는 모두 우리 가 createClasLoader 방법 으로 만 든 ClassLoader 이 고, ParentClassLoader 는 외층 용기 의 CurrentClassLoader 이 며, SystemClassLoader 가 이 예 에 있 는 것 을 발견 했다.
이제 우리 스스로 애플 리 케 이 션 서버 를 만 드 는 것 을 막 을 만 한 것 은 아무것도 없다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
m1 이클립스에 oracle cloud (오라클 클라우드)연결하기m1에는 oracle이 설치되지 않는다.... 큰맘먹고 지른 m1인데 oracle이 설치되지 않는다니... 하지만 이뻐서 용서가 된다. 이거 때문에 웹 개발 국비수업을 듣는 도중에 몇번 좌절하고 스트레스를 크게 받았...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.