一、静态代理
1.静态代理:自己创建一个java类,表示代理类 特点:实现简单、易理解
缺点:当目标类增加时,代理类也要增加。
二、动态代理
1.动态代理是指代理对象是在jvm运行时根据反射机制动态生成的,动态代理不需要代理类(java源文件)
2.动态代理其实就是在jvm运行阶段创建的class字节码,并加载到jvm中
3.动态代理的实现方式常用的有两种:使用JDK代理,与通过CGLlB动态代理。
##动态代理的实现
1.jdk动态理解:使用java反射包中的类和接口实现动态d代理功能,反射包java.lang.reflect .里面有三个类:invocationHandler、Method、Proxy
2.cglib动态:是第三方工具库
1> cglib的原理是继承,通过继承目标类,创建它的子类,在子类中重写父类的方法,修改功能
2>因为cglib是继承,重写方法,所以要求目标类不能是final,方法也不能是final
3. Interface InvocationHandler
public interface InvocationHandler
InvocationHandler是由代理实例的调用处理程序实现的接口 。
每个代理实例都有一个关联的调用处理程序。 当在代理实例上调用方法时,方法调用将被编码并分派到其调用处理程序的invoke方法。
1)InvocationHandler接口(调用处理器):就一个方法 invoke()
invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能就写在
invoke()方法中。
4.Method
method.invoke(目标对象,目标方法参数)
5.Proxy
proxy类:核心的对象,创建代理对象。之前创建对象都是new类的构造方法()
现在我们是使用proxy类的方法,代替new的使用。
方法:静态方法 newProxyInstance()
作用是:创建代理对象,等同于静态代理中的TaoBao taoBao=new TaoBao()
我们来观察方法原型
public static Object newProxyInstance( ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException
参数:
ClassLoader loader 类加载器,负责向内存中加载对象的,使用反射机制获取对象的classLoader,
如何获取? 类 a, a.getCalss().getClassLoader(),目标对象的类加载器
这里我们细分:每一个类都继承Object类,在Object中有一个getClass方法,表示 类对象的运行时类的Class对象。 而Class类里面有一个public ClassLoader getClassLoader()方法
Class<?>[] interfaces: 接口,目标对象实现的接口,也是反射获取的
InvocationHandler h : 我们自己写的,代理类要完成的功能
返回值也就是代理对象
6.动态代理实现
public class DailiInvo implements InvocationHandler {
private Person p;
public DailiInvo(Person p){
this.p = p;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object invoke = method.invoke(p, args);
System.out.println("增强" + invoke.toString());
return invoke;
}
}
public static void main(String[] args) {
Person p = new Lisi();
InvocationHandler dailiInvo = new DailiInvo(p);
Person o = (Person)Proxy.newProxyInstance(p.getClass().getClassLoader(), p.getClass().getInterfaces(), dailiInvo);
o.getName("hahahah");
}
public interface Person {
String getName(String name);
}
public class Lisi implements Person {
@Override
public String getName(String name) {
System.out.println(name + "实现类");
return "基础功能";
}
}