(인터페이스가 아닌) 추상 클래스의 프록시를 생성하기위한 java.lang.reflect.Proxy의 대안
문서 에 따르면 :
[
java.lang.reflect.
]Proxy
는 동적 프록시 클래스 및 인스턴스를 만들기위한 정적 메서드를 제공하며, 이러한 메서드에 의해 만들어진 모든 동적 프록시 클래스의 수퍼 클래스이기도합니다.
newProxyMethod
방법 (동적 프록시 생성을 담당)은하기 특성을 갖는다 :
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
불행히도 이것은 특정 인터페이스를 구현하는 대신 특정 추상 클래스 를 확장 하는 동적 프록시를 생성하는 것을 방지 합니다. 이것은 "모든 동적 프록시의 수퍼 클래스"를 고려 하여 다른 클래스가 수퍼 클래스가되는 것을 방지 하므로 의미 가 있습니다.java.lang.reflect.Proxy
따라서 특정 추상 클래스에서 상속java.lang.reflect.Proxy
하는 동적 프록시를 생성 하여 추상 메서드에 대한 모든 호출을 호출 핸들러로 리디렉션 할 수 있는 대안이 있습니까?
예를 들어 추상 클래스가 있다고 가정합니다 Dog
.
public abstract class Dog {
public void bark() {
System.out.println("Woof!");
}
public abstract void fetch();
}
다음을 수행 할 수있는 수업이 있습니까?
Dog dog = SomeOtherProxy.newProxyInstance(classLoader, Dog.class, h);
dog.fetch(); // Will be handled by the invocation handler
dog.bark(); // Will NOT be handled by the invocation handler
Javassist (참조 ProxyFactory
) 또는 CGLIB를 사용하여 수행 할 수 있습니다 .
Javassist를 사용한 Adam의 예 :
나는 (Adam Paynter) Javassist를 사용하여이 코드를 작성했습니다.
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass(Dog.class);
factory.setFilter(
new MethodFilter() {
@Override
public boolean isHandled(Method method) {
return Modifier.isAbstract(method.getModifiers());
}
}
);
MethodHandler handler = new MethodHandler() {
@Override
public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
System.out.println("Handling " + thisMethod + " via the method handler");
return null;
}
};
Dog dog = (Dog) factory.create(new Class<?>[0], new Object[0], handler);
dog.bark();
dog.fetch();
이 출력을 생성합니다.
씨! 메소드 핸들러를 통해 public abstract void mock.Dog.fetch () 처리
이러한 경우에 할 수있는 일은 추상 클래스의 기존 메서드로 호출을 리디렉션하는 프록시 처리기를 갖는 것입니다.
You of course will have to code it, however it's quite simple. For creating your Proxy, you'll have to give him an InvocationHandler
. You'll then only have to check the method type in the invoke(..)
method of your invocation handler. But beware : you'll have to check the method type against the underlying object associated to your handler, and not against the declared type of your abstract class.
If I take as an example your dog class, your invocation handler's invoke method may look like this (with an existing associated dog subclass called .. well ... dog
)
public void invoke(Object proxy, Method method, Object[] args) {
if(!Modifier.isAbstract(method.getModifiers())) {
method.invoke(dog, args); // with the correct exception handling
} else {
// what can we do with abstract methods ?
}
}
However, there is something that keep me wondering : I've talked about a dog
object. But, as the Dog class is abstract, you can't create instances, so you have existing subclasses. Furthermore, as a rigorous inspection of Proxy source code reveals, you may discover (at Proxy.java:362) that it is not possible to create a Proxy for a Class object that does not represents an interface).
So, apart from the reality, what you want to do is perfectly possible.
'Program Tip' 카테고리의 다른 글
AngularUI를 AngularJS에 통합하는 방법은 무엇입니까? (0) | 2020.10.10 |
---|---|
Python 3 용 패키지를 설치하려면 pip 또는 pip3? (0) | 2020.10.10 |
Eclipse의 다른 Java 프로젝트에서 가져 오기 (0) | 2020.10.10 |
최고의 Java QR 코드 생성기 라이브러리는 무엇입니까? (0) | 2020.10.10 |
저렴한 MSDN 구독? (0) | 2020.10.10 |