需要实现 MethodInterceptor 接口
代理类无需实现自己的接口
特点:CGLib采用了非常底层的字节码技术,
其原理是通过字节码技术为一个类创建子类,
并在子类中采用方法拦截的技术拦截所有父类方法的调用,
顺势织入横切逻辑
对比: CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,
但是CGLib在创建代理对象时所花费的时间却比JDK多得多,
所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,
反之,使用JDK方式要更为合适一些。
同时,由于CGLib由于是采用动态创建子类的方法,
对于final方法,无法进行代理
实现方式一
ServiceImpl.java
public class ServiceImpl {
public void sendmessage1 () {
System.out.println("send message1");
}
public void sendmessage2 () {
System.out.println("send message2");
}
}
MyCglibProxy.java
public class MyCglibProxy<T> implements MethodInterceptor {
T target;
public T getProxy(T target) {
this.target = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return (T)enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("cglib start exec ---");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("cglib end exec ---");
return result;
}
}
Test.java
public static void main(String[] args) {
MyCglibProxy<ServiceImpl> myCglibProxy = new MyCglibProxy();
ServiceImpl proxy = myCglibProxy.getProxy(new ServiceImpl());
proxy.sendmessage1();
proxy.sendmessage1();
}
console
cglib start exec ---
send message1
cglib end exec ---
cglib start exec ---
send message1
cglib end exec ---
实现方式二
public class MyCglibProxy2 {
public static void main(String[] args) {
ServiceImpl service = new ServiceImpl();
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(service.getClass());
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
System.out.println("cglib start exec ---");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println("cglib end exec ---");
return result;
});
ServiceImpl o = (ServiceImpl)enhancer.create();
o.sendmessage1();
o.sendmessage2();
}
static class ServiceImpl {
public void sendmessage1 () {
System.out.println("send message1");
}
public void sendmessage2 () {
System.out.println("send message2");
}
}
}