Этот вопрос отвечает на обработку абстрактных типов методов; но как проксировать не абстрактную часть методов? Реализация абстрактных методов во время выполнения?
Как я могу выполнить следующее для вызова sayHello()
?
пакет cglibtest;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CGLibTest
{
public static void main(String... args)
{
MyAbstract instance = (MyAbstract)Enhancer.create(MyAbstract.class, new MyInterceptor(42));
System.out.println("Value from instance: " + instance.valueMethod());
System.out.println("Value from instance: " + instance.sayHello());
}
public static class MyInterceptor implements MethodInterceptor
{
private final Object constantValue;
public MyInterceptor(Object constantValue)
{
this.constantValue = constantValue;
}
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable
{
if ("valueMethod".equals(method.getName()))
return(constantValue);
else
return(null);
}
}
public static abstract class MyAbstract
{
public abstract int valueMethod();
public String sayHello() { return "Hello" };
}
}
Созданный вами перехватчик уже отменяет все методы, независимо от того, является ли он abstract
или нет. Что вы, кажется, пропустили, так это то, как вызвать оригинальный метод, который вы переопределили:
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable
{
if ("valueMethod".equals(method.getName()))
return constantValue;
else if("sayHello".equals(method.getName())) {
System.out.println("before original sayHello()");
// equivalent of saying super.sayHello() inside subclass
Object result=proxy.invokeSuper(obj, args);
System.out.println("after original sayHello()");
return result;
}
else return null;
}
abstract
класс. Но вы можете реализовать несколько интерфейсов; cglib отражает это, предоставляя альтернативный метод Enhancer.create
принимающий массив Class
интерфейса es. Но вы можете создавать разные прокси для разных abstract
классов, используя только одну реализацию перехватчика; в этом случае, насколько я понял, MethodProxy
который передается вашему методу intercept
, всегда будет подходить для текущего вызываемого метода. Но, конечно, вы всегда можете реализовать несколько разных перехватчиков.