一、cglib代理
cglib是一个强大、高性能的字节码生成库,它用于在运行时扩展Java类和实现接口;本质上它是通过动态的生成一个子类去覆盖所要代理的类(非final修饰的类和方法)。Enhancer可能是CGLIB中最常用的一个类,和jdk中的Proxy不同的是,Enhancer既能够代理普通的class,也能够代理接口。Enhancer创建一个被代理对象的子类并且拦截所有的方法调用(包括从Object中继承的toString和hashCode方法)。Enhancer不能够拦截final方法,例如Object.getClass()方法,这是由于Java final方法语义决定的。基于同样的道理,Enhancer也不能对final类进行代理操作。
二、实现
实体类
package com.sunshine.boot.proxy.cglib;
public class ServiceB {
public void test1() {
System.out.println("我是serviceB的test1方法");
this.test2();
}
public void test2() {
System.out.println("我是serviceB的test2方法");
}
}
代理类
package com.sunshine.boot.proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* cglib动态代理类
*/
public class CglibProxyTest implements MethodInterceptor {
/**
* 目标对象
*/
private Object target;
public CglibProxyTest(Object target) {
this.target = target;
}
/**
* 代理对象方法拦截器
* @param o 代理对象
* @param method 被代理的类的方法,
* @param objects 调用方法传递的参数
* @param methodProxy 方法代理对象
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("执行方法"+method.getName());
System.out.println(method.getName()+"-before...");
Object result = methodProxy.invokeSuper(o, objects);
System.out.println(method.getName()+"-after...");
return result;
}
public static <T> T createProxy(T target) {
CglibProxyTest cglibProxyTest = new CglibProxyTest(target);
Enhancer enhancer = new Enhancer();
enhancer.setCallback(cglibProxyTest);
enhancer.setSuperclass(target.getClass());
return (T) enhancer.create();
}
}
三、测试
package com.sunshine.boot.proxy;
import com.sunshine.boot.proxy.cglib.ServiceB;
import com.sunshine.boot.proxy.jdk.IService;
import com.sunshine.boot.proxy.jdk.ServiceA;
public class ProxyTest {
public static void main(String[] args) {
// jdk
// IService proxyA = JDKProxyTest.createProxy(new ServiceA(), IService.class);
// proxyA.test1();
// cglib
ServiceB proxy = CglibProxyTest.createProxy(new ServiceB());
proxy.test1();
}
}
结果:
执行方法test1
test1-before...
我是serviceB的test1方法
执行方法test2
test2-before...
我是serviceB的test2方法
test2-after...
test1-after...从结果可以看出cglib可以代理test1方法中test2方法