静态代理和动态代理的简单实现

来源:互联网 发布:java单引号和双引号 编辑:程序博客网 时间:2024/06/01 08:54

老生常谈的问题,spring的aop是什么,用到的设计模式是什么,进而又会谈到静态代理和动态代理上。之前看过一些这方面的文章,也照着敲了一些代码,可是coding这个事啊,总是写了忘,忘了写。今天就简单记录一下

  • 代理是什么
    • 代理能降低代码耦合度,将枝节性代码和功能性代码分开
  • 没有代理会怎样
    • 代码之间耦合度较高,移植困难,可重用性降低
    • 枝节性代码应该监视着功能性代码,然后采取行动,而不是功能性代码通知枝节性代码采取行动。这好比吟游诗人应该是主动记录骑士的功绩而不是骑士主 动要求诗人记录自己的功绩
  • 应用
    • AOP 实现
    • 权限控制
    • 日志控制
    • 事务管理
  • 静态代理和动态代理区别

    • 静态代理
      1. 一个抽象对象(从代码实现上讲,并不是必须的)
      2. 代理类 — 拥有真实类的对象
      3. 委托类
      4. 每个委托类需要一个代理类
    • 动态代理
      1. 解决静态代理问题
      2. 代码膨胀
      3. 代理类需要事先知道被代理对象
      4. 实现统一的代理对象
  • 好了,上面这些唠完了,来看一下代码,这里只是一些简单的实现,更加复杂的可以参考别人的代码

静态代理
1. 接口类。其实这里可以不写这个公共接口。它的作用只是体现了面向接口编程

 /** * 打卡 * / public interface Clock {    void startWork();    void endWork(); }

2.委托类。即真正的业务类

/*** 上班*/public class Work implements Clock {    @Override    public void startWork() {    System.out.println("写代码喽!");    }    @Override    public void endWork() {    System.out.println("回家加班喽!");    }}

3.代理类。持有委托类对象。

/**  * 代理  */ public class WorkProxy implements Clock {     private Work work;     public WorkProxy(Work work) {         this.work = work;     }     @Override     public void startWork() {         System.out.println("上班打卡");         work.startWork();     }     @Override     public void endWork() {         System.out.println("下班打卡");         work.endWork();     } }

4.测试类

/*** 测试*/public class Test {  public static void main(String[] args) {      //如果不使用接口      Work work = new Work();      WorkProxy workProxy = new WorkProxy(work);      workProxy.startWork();      workProxy.endWork();      //使用接口的话,这里可以方便的使用多态      //Clock clock = new Work();      Clock clock = new WorkProxy(new Work());      clock.startWork();  }}

动态代理

  1. 公共接口和实现类copy上面的
  2. 这里再新增一个实现类。体现动态代理一次代理多处使用的优点
/*** 学习*/public class Study implements Clock {    @Override    public void startWork() {        System.out.println("我要学习了");    }    @Override    public void endWork() {        System.out.println("放学回家了");    }}

3.代理类 持有委托类对象 实现反射里面的InvocationHandler接口即可

public class DynamicProxy implements InvocationHandler {    private Object object;    public DynamicProxy(Object target) {        this.object = target;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("早上9点 上班打卡!");        Object result = method.invoke(object, args);        System.out.println("晚上9点 下班打卡!");        return result;    }}

4.测试类

/*** 测试*/public class Test {    public static void main(String[] args) {        //DynamicProxy proxy = new DynamicProxy(new Study());        DynamicProxy proxy = new DynamicProxy(new Work());        Clock clock = (Clock)       Proxy.newProxyInstance(Clock.class.getClassLoader()        , Work.class.getInterfaces(), proxy);        clock.startWork();    }}
原创粉丝点击