Я хочу перехватить метод следующего простого класса:
public class MessageWriter {
public void writeMessage() {
System.out.print("method");
}
}
с помощью перехватчика методов CGLIB:
import java.lang.reflect.Method;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.print("Cglib ");
Object res = method.invoke(obj, args);
System.out.print(" proxy!");
return res;
}
}
И я могу получить cglib прокси с помощью cglib Enchancer:
CglibInterceptor cglibInterceptor = new CglibInterceptor(target);
MessageWriter cgLibProxy = (MessageWriter) Enhancer.create(MessageWriter.class, cglibInterceptor);
System.out.println("\ncglib proxy: ");
cgLibProxy.writeMessage();
Этот код работает. Однако я не могу понять, как получить cglib прокси из org.springframework.aop.framework.ProxyFactory
или из org.springframework.cglib.proxy.Enhancer.create()
, т.е. cglib-proxy из Spring?
Если я пишу следующий код:
MessageWriter cgLibSpringProxy = (MessageWriter) org.springframework.cglib.proxy.Enhancer.create(MessageWriter.class, cglibInterceptor);
eclipse подчёркивает create
красным:
UPD
Если более точно переформулировать мой вопрос, меня интересует, можно ли как-нибудь указать в коде, что нужно использовать именно CGlib прокси, в случае, если целевой класс реализует интерфейс? Ведь "по умолчанию , когда целевой объект, оснащаемый советом, реализует какой-то интерфейс, для создания экземпляров прокси целевого объекта Spring будет использовать динамический прокси JDK". Вроде как в конфигурационном файле для этого можно указать
<aop:config proxy-target-class="true">
<!-- other beans defined here... -->
</aop:config>
а вот в коде это как-нибудь можно сделать? И вроде как у класса ProxyFactory
есть метод setProxyTargetClass
:
ProxyFactory pf = new ProxyFactory () ;
pf.setProxyTargetClass(true);
но по описанию в документации я всё-таки не поняла, ТОЧНО ли установка этого метода в true
обязывает Spring использовать именно CGLIB для создания прокси? Вроде как нет? Из документации о ProxyConfig.setProxyTargetClass():)
Set this to "true" to force proxying for the TargetSource's exposed target class. If that target class is an interface, a JDK proxy will be created for the given interface. If that target class is any other class, a CGLIB proxy will be created for the given class.
На сколько я знаю, CGlib
используется по умолчанию при создании прокси без интерфесов в Spring
:
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
public class SpringAop {
public static class Entity {
public void soSomething() {
System.out.println("doing something");
}
}
public static class Handler implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("before calling method");
Object returnedValue = methodInvocation.proceed();
System.out.println("after calling method");
return returnedValue;
}
}
public static void main(String[] args) {
Entity entity = new Entity();
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTarget(entity);
proxyFactory.addAdvice(new Handler());
Entity entityProxy = (Entity) proxyFactory.getProxy();
entityProxy.soSomething();
}
}
Дополнение:
Дело в том, что если цель (target
) не имеет интерфейсов, то прокси будет создан через наследование от цели. Для этого будет использован cglib
. В противном случае, применяется AspectJ
.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
У меня возник вопрос , если использовать лямбда выражения в java , к примеру в stream api , то программы будут работать быстрее? Я просто где-то слышал...
Доброго времени суток! Как на JavaFX сделать окно Window 2 внутри главного окна Window 1? Те
У меня такая задача, нужно через определенные отрезки времени обмениваться с сайтом информацией и в силу свое малого познания android я делаю...