上次说到,cglib是基于类的动态代理。
因为jdk代理是基于接口,有局限性,如果一个类没有继承接口也想实现动态代理的话,必须就要借助于cglib动态代理了。与JDK代理相比较,cglib的原理是创造一个子类重写父类(要被代理的对象)的方法。
cglib的流程
真实角色:要被代理的对象
代理角色:生成代理类(要继承cglib包里的MethodInterceptor接口) 方法拦截器
public interface MethodInterceptor extends Callback {
Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}
第一个参数是就是被代理的对象的引用,第二个参数是对应的方法的引用,第三个对应的参数,第四个为子类的代理。这个方法是处理实例方法的核心方法,用于实现代理对象增强代码的功能,类比于jdk代理的invoke(),
除此 生成代理对象实例要依靠一个类 Enhancer,他有很多api 最常用的就是下面代码中的
public Object getTarget() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
set父类,也就是要代理的类,
然后setcallback 里面是这个实现拦截器本身的类
然后return enhancer.create() 就获得了一个对象的实例
client角色:调用代理的角色
下面分别贴出代码
真实角色:
package com.heaboy.proxyExcise.cglibProxy;
/**
* @Author:XK
* @Date: Created in 17:34 2022/2/19
* @Description:
**/
public class Student {
public void run(){
System.out.println("学生会跑");
}
}
代理角色:
package com.heaboy.proxyExcise.cglibProxy;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.springframework.cglib.core.MethodInfoTransformer;
import java.lang.reflect.Method;
/**
* @Author:XK
* @Date: Created in 17:34 2022/2/19
* @Description:
**/
public class cglibProxyIm implements MethodInterceptor {
//要代理的类
private Object target;
public cglibProxyIm(Object target){
this.target=target;
}
public Object getTarget() {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("增强代码1");
//方式1
//Object result =methodProxy.invokeSuper(o,objects);
//方式2
Object result = method.invoke(target, objects);
System.out.println("增加功能2");
return result;
}
}
client角色:
package com.heaboy.proxyExcise.cglibProxy;
/**
* @Author:XK
* @Date: Created in 17:40 2022/2/19
* @Description:
**/
public class client {
public static void main(String[] args) {
Student student = new Student();
cglibProxyIm cglibProxyIm = new cglibProxyIm(student);
Student target = (Student)cglibProxyIm.getTarget();
target.run();
}
}