2019.03.01(java基础代理模式)

静态代理模式

结构图:
在这里插入图片描述

  1. 接口
public interface Eat {
    public void eat();
}
  1. 真实类A
public class EatImpl implements Eat {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
  1. 真实类B
public class EatImpl2 implements Eat {
    @Override
    public void eat() {
        System.out.println("狗吃肉");
    }
}
  1. 工厂
public class Factory {
    public static Eat factory(String animal){
        if("cat".equals(animal)){
            return new EatImpl();
        }else if("dog".equals(animal)){
            return new EatImpl2();
        }
        return null;
    }
}
  1. 核心:代理类
public class Proxy implements Eat {
    private Eat eat;
    public Proxy(String animal){
        this.eat = Factory.factory(animal);
    }
    private void start(){
        System.out.println("准备食物");
    }
    private void end(){
        System.out.println("收拾");
    }
    @Override
    public void eat() {
        this.start();
        this.eat.eat();
        this.end();
    }
}
  1. 测试类
public class Test {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String next = sc.next();
        Proxy p = new Proxy(next);
        p.eat();
    }
}

动态代理

第一步:创建Dao接口

public interface EatDao {
    public void eat();
    public void drink();
}

第二步:实现Dao接口

public class EatImpl implements EatDao {
    @Override
    public void eat() {
        System.out.println("吃饭");
    }

    @Override
    public void drink() {
        System.out.println("喝酒");
    }
}

第三步:创建事务类,切面类

public class MyTransaction {
    public void prepare(){
        System.out.println("开启事务");
    }
    public void after(){
        System.out.println("关闭事务");
    }
}

第四步:代理类

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class ObjectInterceptor implements InvocationHandler {
    //目标类
    public EatDao eat;
    //切面类
    public MyTransaction myTransaction;
    public ObjectInterceptor(EatDao eat, MyTransaction myTransaction) {
        this.eat = eat;
        this.myTransaction = myTransaction;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        this.myTransaction.prepare();
        method.invoke(this.eat,args);
        this.myTransaction.after();
        return null;
    }
}

第五步:测试类

public void test1(){
        //要代理的真实类
        EatDao eat = new EatImpl();
        //切面类对象
        MyTransaction myTransaction = new MyTransaction();
        ObjectInterceptor objectInterceptor = new ObjectInterceptor(eat, myTransaction);
        /**
         * 通过proxy类的newProxyInstance方法创建代理对象
         * 第一个参数:eatImpl2.getClass().getClassLoader(),使用objectInterceptor对象的classloader对象来加载我们的代理对象
         * 第二个参数:eatImpl2.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口
         * 中的所有方法
         * 第三个参数:objectInterceptor,我们将代理对象关联到上面的事务类中
         */
        EatDao o = (EatDao) Proxy.newProxyInstance(eat.getClass().getClassLoader(), eat.getClass().getInterfaces(), objectInterceptor);
        o.drink();
        o.eat();
    }

动态代理和静态代理的区别

  1. 静态代理的代理类实现的是Dao层的接口,动态代理的代理类实现的是java.lang.reflect.InvocationHandler这个接口
  2. Dao层接口发生变化,静态代理代理类需要进行相应的改变,而动态代理的代理类不需要进行任何改变

猜你喜欢

转载自blog.csdn.net/qq_34191426/article/details/88067253