代理分为静态代理与动态代理
这里只记录动态代理
动态代理常见的有
JDK动态代理
JDK代理模式需要通过接口来完成(后面做解释)
其过程如下:
定义一个Person接口
//person
public interface Person {
public void doSth();
}
//定义接口实现类
public class Mrxu implements Person{
@Override
public void doSth() {
// TODO Auto-generated method stub
System.out.println("i want to be a good ... ");
}
}
//定义代理类
//JDK代理通过实现InvocationHandler 来完成代理工作
//JDK动态代理
public class JDKProxy implements InvocationHandler{
//代理对象先得获取被代理者的信息才能完成代理工作
private Person target;
//
public Object getInstance(Person target)throws Exception{
this.target=target;
//获取被代理对象类信息
Class<? extends Person> clazz = target.getClass();
//实例化代理对象
return Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("这里是代理人...");
System.out.println("信息代理开始...");
//this.target.doSth();
method.invoke(target, args);
return null;
}
}
//代理测试
public static void main(String[] args) throws Exception {
Person person =(Person) new JDKProxy().getInstance(new Mrxu());
person.doSth();
}
测试结果如下:
这里简单的分析分析代理模式都做了什么。
首先
我们定义了一个Person类接口。然后Mrxu实现了接口
注意:这里的Mrxu就是我们要被代理的对象。且被代理的行为是doSth();
ok。这时候被代理对象有了,我们要有代理人。这里定义的代理者JDKProxy
通过实现InvocationHandler来完成代理。
到现在为止,代理人,被代理人,代理做的事都有了,代理的条件也就齐了。
那么代理是怎么实现的呢?
首先代理人先得获取被代理人信息才能完成代理
getInstance();
生成代理实例对象。
最后完成代理工作。
注意:以上JDK动态代理再获取类实例的时候,是通过接口来完成的。
后续会根据这个进行JDK简单源码的练习。
cglib动态代理
Cglib代理与JDK代理原理相同,都是通过字节码重组来完成代理。
不同的是,JDK是通过接口来完成。Cglib是通过生成子类来重写符类方法来完成
在Cglib中。Enhancer类会帮助我们生成代理子类,只需要指定其被代理符类就行。
具体实现代码如下。
//定义被代理类(也是Cglib需要指定的父类)
public class Mrxu {
public void doSth(){
System.out.println("i am mrxu ,i want do somethinga...");
}
}
注:
Cglib通过实现MethodInterceptor来完成代理工作,需要第三方jar包如下
获取实例,生成代理子类,
public Object getInstance(Class clazz){
Enhancer enhancer=new Enhancer();
//设置生成子类的父类
enhancer.setSuperclass(clazz);
//设置回馈
enhancer.setCallback(this);
return enhancer.create();
}
启用代理。
注意:Cglib被代理对象是其父类。
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// TODO Auto-generated method stub
System.out.println("这里是cglib代理...");
proxy.invokeSuper(obj, args);
return null;
}
proxy.invokeSuper(obj, args);
这里如果代理子类的话,会导致死循环。