Java 8에서는 호출자가 비공용 프록시 인터페이스와 동일한 런타임 패키지에 있지 않은 경우
프록시 인스턴스를 작성하는 데 Proxy.getProxyClass 및 Constructor.newInstance
메소드를 사용하는 코드에 대해 동작 변경을
소개합니다.
Java 7에서, 이러한 메소드를 사용하면 프록시 클래스가 작성됩니다. Java 8에서, 이는
IllegalAccessException과 함께 실패합니다.
분석기가 사용되는 인터페이스 또는 해당 가시성을 항상 판별할 수는 없으므로
이 규칙은 액세스 가능으로 정의되는 경우를 제외하고 Constructor.newInstance(InvocationHandler)의 모든 호출에
플래그를 지정합니다. 규칙은 다음 메소드에 대한 호출을 사용하는
동일한 메소드로 선행되는 Constructor.newInstance(InvocationHandler) 메소드의
호출에 플래그를 지정하지 않습니다.
- 액세스 가능 유형 리터럴로 인터페이스를 정의하는
Proxy.getProxyClass(ClassLoader, Class...) 메소드
Constructor.setAccessible(true) 메소드
플래그 지정된 코드를 검사하여 getProxyClass 메소드가 기타 런타임 패키지에서 호출되는지 및 프록시 인터페이스가
비공용인지 확인하십시오. 예를 들어,
public 키워드가 없는 패키지 레벨 인터페이스는 비공용입니다.
Java 8에서 프록시 클래스를 작성하려면 다음 기술 중 하나를 사용하십시오.
Constructor.setAccessible(true)을 호출하여 액세스 가능한 플래그를 설정하십시오.
Proxy.newProxyInstance 편의 메소드를 사용하십시오.
보안 관리자가 표시되는 경우 두 솔루션 모두 ReflectPermission("newProxyInPackage.{package name}") 권한이
있어야 SecurityException을 막을 수 있습니다.
다음 예제에서는 proxyClass 메소드가
비공용 인터페이스를 인스턴스화하는 경우 코드를 변경하는 방법을 보여줍니다.
기존 코드:
< 보안 범위 class = "코드">
< span class= "JavaKeyword"> public < /span> < span class="JavaType"> Object < /span> instantiateClass(< span class= "JavaType"> Class < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> Exception < /span> {
Object o=null;
o = proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
return o;
}
솔루션 1:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> 오브젝트 < /span> instantiateClass(< span class= "JavaType"> 클래스 < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> 예외 < /span> {
Object o=null;
o = proxyClass.getConstructor(InvocationHandler.class).newInstance(handler);
Constructor c = proxyClass.getConstructor(InvocationHandler.class);
c.setAccessible(true);
o = c.newInstance(handler);
return o;
}
솔루션 2:
< span class="Code"> < span class= "JavaKeyword"> public < /span> < span class="JavaType"> 오브젝트 < /span> instantiateClass(< span class= "JavaType"> 클래스 < ?> < /span> proxyClass, < span class="JavaType">InvocationHandler< /span> handler) throws < span class= "JavaType"> 예외 < /span> {
Object o=null;
o = Proxy.newProxyInstance(proxyClass.getClassLoader(), proxyClass.getInterfaces(), handler);
return o;
}
추가 정보는 다음 클래스에 대한 Java 문서를 참조하십시오.