代理模式及实现

 

代理对象和委托对象继承相同接口,并控制外部对委托对象的访问。

1. 静态代理: 代理类在编译期确定,需要针对为每个接口实现不同的代理。

接口(Human):

public interface Human{
    public void eatFood();
}

委托类(HumanImpl):

public class HumanImpl implements Human{
    public void eatFood(){
        System.out.print("真香!");
    }
}

代理类(HumanProxy):

public class HumanProxy implements Human{
    private Human human;

    public HumanProxy(Human human){
            this.human = human;
    }
    
    public void eatFood(){
        before();
        human.eatFood();
        after();
    }
}

 

2. JDK动态代理: 运行期生成代理类

  在代理类和委托类之间生成中介类,该类实现 InvocationHandler 接口。对委托对象方法的调用会转到中介对象的invoke()方法中,method标识了调用哪一个方法(通过反射获取),args代表方法参数。

public class HumanDynamicProxy implements InvocationHandler{
    //委托对象
    private Human human;
    public HumanDynamicProxy(Human human){
        this.human = human;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        // 使用反射
        Object result = method.invoke(human, args);
        after();
        return result;
    }
}

 

测试代码:

public static void main(String[] args){
    //委托对象
    Human realHuman = new HumanImpl();
    //中介
    InvocationHandler  handler = new HumanDynamicProxy(human);
    //动态代理,需要指定要的实现的接口,使用反射通过接口获取方法名,拼接出类的字符串再构造出代理类
    Human proxy = (Human) Proxy.newProxyInstance(realHuman.getClass().getClassLoader(), realhuman.getClass().getInterfaces(), handler);
    //通过代理类,执行方法;
    proxy.eatFood();

 

3. CGLIB动态代理(委托类不需要实现某接口)

public class Man{
    public void eatFood(){
        System.out.print("真香");
    }
}

 

  生成一个类似的中介类,实现MethodInterceptor接口,方法调用转发到该类的intercept()方法。

class ManMethodInterceptor implements MethodInterceptor{
  private Man man;
  public ManMethodInterceptor(Man man){
    this.man = man;
  }
   @Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable{ before(); Object result = method.invoke(man, args); after(); return result; }

 

  测试代码:

Enhancer enhancer = new Enhancer();
//指定委托目标
enhancer.setSuperclass(Man.class);
//指定中介类
enhancer.setCallback(new ManMethodInterceptor());
//生成代理类
Man man = (Man) enhancer.create();
hello.eatFood();

 

参考:https://blog.csdn.net/a396901990/article/details/26015977

 

posted @ 2018-08-07 21:35  walker993  阅读(228)  评论(0编辑  收藏  举报