1. 区别
- JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
- CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,并覆盖其中方法实现增强,但是因为采用的是继承,所以该类或方法最好不要声明成final, 对于final类或方法,是无法继承的。
2. JDK 动态代理
参考:
1. jdk动态代理举例 == 使用
2. 深度剖析JDK动态代理机制 == 底层剖析
jdk动态代理举例:
public interface Say {
void sayHello(String words);
}
public class SayImpl implements Say {
@Override
public void sayHello(String words) {
System.out.println("hello:" + words);
}
}
public class TestInvocationHandler implements InvocationHandler {
private Object target;
public TestInvocationHandler(Object target) {
this.target=target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("invoke begin");
System.out.println("method :"+ method.getName()+" is invoked!");
method.invoke(target,args);
System.out.println("invoke end");
return null;
}
}
public static void main(String[] args) {
TestInvocationHandler testInvocationHandler = new TestInvocationHandler(new SayImpl());
Say say = (Say)Proxy.newProxyInstance(SayImpl.class.getClassLoader(), SayImpl.class.getInterfaces(), testInvocationHandler );
say.sayHello("my dear");
}
打印输出:
invoke begin
method :sayHello is invoked!
hello:my dear
invoke end
3. CGLib 动态代理
参考:
1. CGLib动态代理原理及实现 == 使用
2. cglib源码分析(四):cglib 动态代理原理分析 == 底层剖析
CGLib 动态代理举例
public class SayHello {
public void say(){
System.out.println("hello everyone");
}
}
public class CglibProxy implements MethodInterceptor{
private Enhancer enhancer = new Enhancer();
public Object getProxy(Class clazz){
//设置需要创建子类的类
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
//通过字节码技术动态创建子类实例
return enhancer.create();
}
//实现MethodInterceptor接口方法
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy proxy) throws Throwable {
System.out.println("前置代理");
//通过代理类调用父类中的方法
Object result = proxy.invokeSuper(obj, args);
System.out.println("后置代理");
return result;
}
}
public class DoCGLib {
public static void main(String[] args) {
CglibProxy proxy = new CglibProxy();
//通过生成子类的方式创建代理类
SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);
proxyImp.say();
}
}
结果输出:
前置代理
hello everyone
后置代理