代理实现形式有哪些?
什么是静态代理和动态代理?
静态代理就是一种形式上的称呼,其实就是对原实现做了又一次封装,实现和”代理“之间是一对一的关系,专职保姆(编译期)
动态代理分为2种,
一种jdk官方的,只能对接口做代理,还要提供接口的实现,生成快,執行慢
一种是cglib,普通类非final可继承,scm字节码技术 生成類慢,執行快
一种是基于AspectJ ,修改目标类字节,织入新内容,编译时动态的织入,不生成新的class
一种基于instrumentation(修改目标类的字节码、类装载的时候动态拦截去修改,基于javaagent) -javaagent:spring-instrument-4.3.8.RELEASE.jar
(类装载的时候 插入动态代理的字节码,不会生成全新的Class )
2个角色:
代理类:加什么功能,就由它在原实现上增强
委托类:原实现
jdk官方的实现是:
这里jvm在runnable期间,创建了代理对象并通过它,对原接口实现做了功能增强。我们要做的,就是在创建代理对象时,告诉jvm要对谁增强,增强做什么。这里要做的事情都放在了invoke方法里,因为我们知道,在代理方法之前会先进入invoke
//参数一:loader:获取实现类的加载器
//参数二:interfaces:获取实现类所实现的接口数组
//参数三:代理要做的事情 注意:这里接收了一个外面的参数,crud的实现类!
CURD user =(CURD) Proxy.newProxyInstance(curdImpl.getClass().getClassLoader(), new Class[]{CURD.class}, new InvocationHandler() {
@Override
/**
* 有了代理对象,下面要做点什么
* proxy:代理对象本身 类似于this
* method:当前具体执行的方法 反射
* args:调用方法传递的实际参数数组 可变参数的底层也是数组(若执行的方法内有参数 则需有args)
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("11");
Object invoke = method.invoke(curdImpl);//反射实现
//将目标类的返回对象紧接着再返回给调用者
return invoke;
}
});
上面的方法Proxy.newProxyInstance(classLoader,interfaces,invocaterHandler),其实是下面几个方法的封装,简化了形式
// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
// 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用
InvocationHandler handler = new InvocationHandlerImpl(..);
// 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });
// 通过反射从生成的类对象获得构造函数对象
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });
// 通过构造函数对象创建动态代理类实例
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });
在JDK动态代理中涉及如下角色:
业务接口Interface、业务实现类target、业务处理类Handler、JVM在内存中生成的动态代理类$Proxy0
动态代理的过程:
第一:Proxy通过传递给它的参数(interfaces/invocationHandler)生成代理类$Proxy0;
第二:Proxy通过传递给它的参数(ClassLoader)来加载生成的代理类$Proxy0的字节码文件;
cglib的实现:
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class CglibMethodInterceptor implements MethodInterceptor {
public Object CglibProxyGeneratory(Class target) {
// 创建加强器,用来创建动态代理类
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("before");
Object result = proxy.invokeSuper(obj, args); //Object result = method.invoke(target, args);
System.out.println("after");
return result;
}
}