3.6. 배포에서 프로그래밍 방식으로 Class Loader 사용

3.6.1. 배포에서 클래스 및 리소스 프로그래밍 방식으로 로드

애플리케이션 코드에서 클래스와 리소스를 프로그래밍 방식으로 찾거나 로드할 수 있습니다. 선택하는 방법은 여러 요인에 따라 다릅니다. 이 섹션에서는 사용 가능한 방법을 설명하고 사용 시기를 위한 지침을 제공합니다.

Class.forName() 메서드를 사용하여 클래스 로드

Class.forName() 메서드를 사용하여 클래스를 프로그래밍 방식으로 로드하고 초기화할 수 있습니다. 이 방법에는 두 개의 서명이 있습니다.

  • class.forName(String className):

    이 서명에는 로드에 필요한 클래스의 이름인 하나의 매개변수만 사용됩니다. 이 메서드 서명을 사용하면 현재 클래스의 클래스 로더에 의해 클래스가 로드되고 기본적으로 새로 로드된 클래스를 초기화합니다.

  • class .forName(String className, 부울 초기화, ClassLoader 로더):

    이 서명에는 클래스 이름, 클래스를 초기화할지 여부를 지정하는 부울 값, 클래스를 로드해야 하는 ClassLoader 의 세 가지 매개 변수가 필요합니다.

3가지 인수 서명은 클래스를 프로그래밍 방식으로 로드하는 데 권장되는 방법입니다. 이 서명을 사용하면 로드 시 대상 클래스를 초기화할지 여부를 제어할 수 있습니다. JVM이 호출 스택을 검사하여 사용할 클래스 로더를 결정할 필요가 없으므로 클래스 로더를 가져오고 제공하는 것이 더 효율적입니다. 코드가 포함된 클래스 이름이 CurrentClass라고 가정하면 CurrentClass .class.getClassLoader() 메서드를 사용하여 클래스의 클래스 로더를 얻을 수 있습니다.

다음 예제에서는 TargetClass 클래스를 로드하고 초기화할 클래스 로더를 제공합니다.

Class<?> targetClass = Class.forName("com.myorg.util.TargetClass", true, CurrentClass.class.getClassLoader());

지정된 이름으로 모든 리소스 찾기

리소스의 이름과 경로를 알고 있는 경우 직접 로드하는 가장 좋은 방법은 표준 JDK(Java Development Kit) Class 또는 Class Loader API를 사용하는 것입니다.

  • 단일 리소스 로드.

    배포에서 클래스 또는 다른 클래스와 동일한 디렉터리에 있는 단일 리소스를 로드하려면 Class.getResourceAsStream() 메서드를 사용할 수 있습니다.

    InputStream inputStream = CurrentClass.class.getResourceAsStream("targetResourceName");
  • 단일 리소스의 모든 인스턴스를 로드합니다.

    배포의 클래스 로더에 표시되는 단일 리소스의 모든 인스턴스를 로드하려면 Class.getClassLoader().getResources(String resourceName) 메서드를 사용합니다. 여기서 resourceName 은 리소스의 정규화된 경로입니다. 이 메서드는 지정된 이름으로 클래스 로더에서 액세스할 수 있는 리소스에 대한 모든 URL 오브젝트의 Enumeration을 반환합니다. 그런 다음, openStream() 메서드를 사용하여 각 스트림을 열도록 URL 배열을 반복할 수 있습니다.

    다음 예제에서는 리소스의 모든 인스턴스를 로드하고 결과를 반복합니다.

    Enumeration<URL> urls = CurrentClass.class.getClassLoader().getResources("full/path/to/resource");
    while (urls.hasMoreElements()) {
        URL url = urls.nextElement();
        InputStream inputStream = null;
        try {
            inputStream = url.openStream();
            // Process the inputStream
            ...
        } catch(IOException ioException) {
            // Handle the error
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (Exception e) {
                    // ignore
                }
            }
        }
    }
    참고

    URL 인스턴스는 로컬 스토리지에서 로드되므로 openConnection() 또는 기타 관련 방법을 사용할 필요가 없습니다. 스트림은 코드의 복잡성을 최소화하고 훨씬 더 간단하게 사용할 수 있습니다.

  • 클래스 로더에서 클래스 파일을 로드합니다.

    클래스가 이미 로드된 경우 다음 구문을 사용하여 해당 클래스에 해당하는 클래스 파일을 로드할 수 있습니다.

    InputStream inputStream = CurrentClass.class.getResourceAsStream(TargetClass.class.getSimpleName() + ".class");

    클래스가 아직 로드되지 않은 경우 클래스 로더를 사용하고 경로를 변환해야 합니다.

    String className = "com.myorg.util.TargetClass"
    InputStream inputStream = CurrentClass.class.getClassLoader().getResourceAsStream(className.replace('.', '/') + ".class");