자바 Gradle 프로젝트 의 자원 올 바른 획득 방식
자바 Gradle 프로젝트 는 자원 접근 과 관련 됩 니 다.일반적으로 현재 프로젝트 에 필요 한 자원 파일 을 resources 폴 더 에 모두 배치 합 니 다.main 파일 의 source code 든 test 폴 더 의 test code 든.
리 소스 폴 더 의 자원 을 가 져 오 는 것 과 다소 관련 이 있 습 니 다.본 고 는 리 소스 폴 더 의 자원 을 어떻게 가 져 오 는 지 상세 하 게 정리 하 는 것 이 목적 입 니 다.
두 개의 getResource 방법
간단 한 자바 Gradle 프로젝트(simpleresource 라 고 함)의 프로젝트 구 조 를 봅 니 다.
우선 이 프로젝트 는 build 를 실행 한 후 루트 디 렉 터 리 아래 에 out 디 렉 터 리 를 만 듭 니 다.이 디 렉 터 리 는 모든 컴 파일 결과(class 파일 및 자원 파일)를 저장 합 니 다.위의 그림 에서 보 듯 이 production 폴 더 는 source code 에 대응 하고 test 폴 더 는 test code 에 대응 합 니 다.
모든 자원 은 resources 폴 더 내부 에 저 장 됩 니 다.프로그램 이 실 행 될 때 가 져 온 자원 은 이 resources 폴 더 의 자원 입 니 다.
우리 가 가장 많이 사용 하 는 자원 을 얻 는 방법 은 두 개의 Class.getResource 와 ClassLoader.getResource 가 있 습 니 다.그러나 이 두 가지 방법 은 전달 매개 변수 와 결과 가 다 릅 니 다.다음은 이 두 가지 방법 파라미터 와 반환 값 을 상세 하 게 분석 하 겠 습 니 다.
ClassLoader 의 getResource 방법 을 먼저 보십시오.클래스 캐리어 대상 만 가 져 오 면 됩 니 다.(가 져 오 는 방식 은 더 이상 설명 하지 않 습 니 다)이 방법의 API 문서 에 대한 설명 을 먼저 보십시오.
Finds the resource with the given name. A resource is some data (images, audio, text, etc) that can be accessed by class code in a way that is independent of the location of the code. The name of a resource is a '/'-separated path name that identifies the resource.
This method will first search the parent class loader for the resource; if the parent is null the path of the class loader built-in to the virtual machine is searched. That failing, this method will invoke findResource(String) to find the resource.
이 설명 을 통 해 알 수 있 듯 이 자원 을 제공 하 는 경로(내 가 이해 하 는 것 은 상대 적 인 경로)입 니 다.정상 적 인 상황 에서 이 방법 은 자원 의 완전한 URL 로 돌아 갑 니 다.전달 하 는 매개 변 수 는 중요 한 주의사항 이 있 습 니 다.바로 전달 하 는 매개 변 수 는/로 시작 할 수 없다 는 것 입 니 다.이것 도 제 가 왜 이 매개 변 수 를 자원 의 경로 라 고 부 르 는 지 예 를 들 어 보 겠 습 니 다.
URL test = this.getClass().getClassLoader().getResource("/");
상기 코드 를 실행 한 결 과 는 다음 과 같 습 니 다.
simpleresource 의 프로젝트 구 조 를 참고 하여 com.mainres 의 파일 을 정확하게 가 져 오 는 올 바른 방법 은:
String name = "com/mainres/testmain.txt";
URL test = this.getClass().getClassLoader().getResource(name);
결 과 는:
자원 경 로 를 나타 내 는 문자열 에/를 추가 하면 가 져 온 URL 은 null 입 니 다.
String name = "/com/mainres/testmain.txt";
URL test = this.getClass().getClassLoader().getResource(name);
앞에서 말 한 바 와 같이 클래스 로 더 를 사용 하여 자원 을 가 져 오 는 방식 으로 전달 하 는 매개 변 수 는 자원 상대 경로(resources 폴 더 의 경로 에 비해)입 니 다.상대 경로 인 만큼 자연 매개 변 수 는/시작 할 수 없습니다.
매개 변수 가 빈 문자열 로 전 달 될 때 경 로 를 얻 는 것 은 classes 폴 더 의 절대적 인 경로 이지 만 정확 한 자원 경 로 를 전달 할 때 경 로 는 resources 폴 더 의 자원 경로 입 니 다.
String name = "";
URL test = this.getClass().getClassLoader().getResource(name);
제 이 해 는 본질 적 으로 이 방법 을 통 해 가 져 온 실제 클래스 로 더 에 불 러 온 class 바이트 디 렉 터 리 입 니 다.따라서 빈 문자열 을 사용 하면 실제 출력 된 것 은 classes 폴 더 의 절대 경 로 를 볼 수 있 습 니 다.정확 한 자원 경 로 를 전달 할 때 코드 차원 을 바 꾸 고 classes 폴 더 와 같은 등급 의 resources 폴 더 에 있 는 자원 을 가 져 옵 니 다.
Class 의 getResource 방법 을 다시 봅 니 다.
이 방법 으로 매개 변 수 를 전달 하 는 것 이/로 시작 하 는 것 인지 에 따라 서로 다른 결과 가 발생 할 수 있 고 이 방법 을 사용 하 는 것 도 ClassLoader 의 getResource 방법 과 헷 갈 리 기 쉬 우 므 로 본 고 는 전달 하 는 매개 변수 가/로 시작 하 는 지 여 부 를 여러 번 강조 한다.
먼저 전달 매개 변수 가'와/인 두 가지 상황 에서 얻 은 결 과 를 봅 니 다.
빈 문자열 사용 하기:
String name = "";
URL test = this.getClass().getResource(name);
실행 결과:
사용/
String name = "/";
URL test = this.getClass().getResource(name);
실행 결 과 는:
가장 큰 차이 점 은 빈 문자열 을 사용 하 는 것 입 니 다."가 져 온 경 로 는 가방 의 디 렉 터 리 에 비해 가 져 온 것 입 니 다.가 져 온 경 로 는 클래스 로 더 가 class 파일 을 불 러 오 는 디 렉 터 리 입 니 다.이것 은 ClassLoader 의 getResource 방법 으로"문자열 의 결 과 를 전달 하 는 것 과 같 습 니 다.따라서 자원 파일 을 정확하게 가 져 오 려 면,
그렇다면 클 라 스 의 getResource 방법 은 다음 과 같다.
String name = "/com/mainres/testmain.txt";
URL test = this.getClass().getResource(name);
실행 결과:
따라서 다시 말하자면 두 가지 방법 으로 파 라 메 터 를 전달 하 는 것 이 헷 갈 리 는 것 을 방지 하 는 간단 한 기억 방식 은 Class 의 getResource 방법 을 사용 하 는 것 입 니 다.
사실 Class 클래스 의 getResource 방법 을 참고 하 십시오.
public java.net.URL getResource(String name) {
name = resolveName(name);
ClassLoader cl = getClassLoader0();
if (cl==null) {
// A system class.
return ClassLoader.getSystemResource(name);
}
return cl.getResource(name);
}
본질 적 으로 이것 도 ClassLoader 의 getResource 방법 을 호출 합 니 다.그 중에서 resolveName 이라는 방법 은 전 달 된 매개 변 수 를 변환 합 니 다.
private String resolveName(String name) {
if (name == null) {
return name;
}
if (!name.startsWith("/")) {
Class<?> c = this;
while (c.isArray()) {
c = c.getComponentType();
}
String baseName = c.getName();
int index = baseName.lastIndexOf('.');
if (index != -1) {
name = baseName.substring(0, index).replace('.', '/')
+"/"+name;
}
} else {
name = name.substring(1);
}
return name;
}
전 달 된 인자 가/가 있 을 때 resolve Name 은 제 거 된 문자열 을 되 돌려 주 고 마지막 으로 ClassLoader 의 getResource 방법 을 호출 합 니 다.작은 매듭
본 고 는 Class 와 ClassLoader 의 getResource 방법의 차 이 를 비교 하 였 으 며,단순히 자원 획득 측면 에서 볼 때 최종 호출 된 것 은 모두 ClassLoader 의 getResource 방법 입 니 다.
간단 한 기억 은 Class 의 getResource 방법 을 사용 하 는 것 입 니 다.자원 경 로 는 추가/가 필요 하지만 ClassLoader 의 getResource 방법 을 사용 하면 추가/가 필요 없습니다.
이상 의 자바 Gradle 프로젝트 의 자원 정확 한 획득 방식 은 바로 편집장 이 여러분 에 게 공유 하 는 모든 내용 입 니 다.여러분 에 게 참고 가 되 고 저 희 를 많이 사랑 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JPA + QueryDSL 계층형 댓글, 대댓글 구현(2)이번엔 전편에 이어서 계층형 댓글, 대댓글을 다시 리팩토링해볼 예정이다. 이전 게시글에서는 계층형 댓글, 대댓글을 구현은 되었지만 N+1 문제가 있었다. 이번에는 그 N+1 문제를 해결해 볼 것이다. 위의 로직은 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.