Java 动态代理

来源:互联网 发布:深睡眠和浅睡眠 知乎 编辑:程序博客网 时间:2024/06/14 01:52


一丶静态代理        


在了解动态代理之前, 先来了解一下静态代理. 通过一下实例进行讲解.

// 在这里创建一个业务接

public interface Subject {    void doSomething();}

// 创建业务实现类

public class RealSubject implements Subject {    @Override    public void doSomething() {        System.out.println("Do Something ...");    }}

// 创建代理类

public class ProxySubject implements Subject {    // 创建一个实现业务操作的实例    private Subject realSubject = new RealSubject();    @Override    public void doSomething() {        // 添加自己的业务操作        System.out.println("Proxy Before ...");        // 通过这里调用真实的业务操作        realSubject.doSomething();        // 添加自己的业务操作        System.out.println("Proxy After ...");    }}

// 测试静态代理

public class TestStaticProxy {    public static void main(String[] args) {        // 实现一个代理实例        Subject subject = new ProxySubject();        // 通过代理实例调用代理方法, 代理方法中调用实际的业务方法        subject.doSomething();    }}


// 运行结果

Proxy Before ...Do Something ...Proxy After ...


             通过以上的过程会发现, 静态代理生成的关联类是非常繁琐的, 并且在代理类中需要加载业务实现类的实例, 如果这个代理类需要代理很多业务实现类, 就需要加载大量的实例, 这是一件非常繁琐的事, 并且会使我们得代码高耦合,显然是不符合代码简洁的要求.


二丶动态代理


通过静态代理的例子, 我们发现静态代理虽然能实现代理的操作, 但是代码过于繁琐, 下面讲一个动态代理的例

// 在这里创建一个业务接口

public interface Subject {    void doSomething();}

// 创建业务实现类

public class RealSubject implements Subject {    @Override    public void doSomething() {        System.out.println("Do Something ...");    }}

// 创建代理类

public class DynamicProxy implements InvocationHandler {    // 一个接口实现类对象    private Subject realSubjec;    public DynamicProxy(Subject realSubjec) {        this.realSubjec = realSubjec;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        System.out.println("Proxy Before ...");// 通过反射的方法调用业务方法        method.invoke(realSubjec,args);        System.out.println("Proxy After ...");        return null;    }}
// 测试代理类

public class TestDynamicProxy {    public static void main(String[] args) {        // 生成业务实现类对象        Subject realSubjet = new RealSubject();        // 传入代理类中        DynamicProxy handler = new DynamicProxy(realSubjet);        // 调用Proxy.newProxyInstance 创建一个代理对象        // 第一个参数是创建代理对象需要用到的ClassLoader 调用handler和Subject都行         // 第二个参数是业务实现类所继承的接口, 生成的代理对象也会继承该接口, 所以可以强制类型转换为Subject        // 第三个参数是所关联的代理类对象, 代理对象通过调用接口中的方法, 对应到代理类对象中的invoke 方法        //      通过反射调用业务实现类中的业务方法        Subject o = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(),                 realSubjet.getClass().getInterfaces(), handler);        // 将doSomething方法名和参数(如果有) 传入 handler的invoke方法中        o.doSomething();     }}

// 运行结果

Proxy Before ...Do Something ...Proxy After ...

   这里运行结果和静态代理的结果是一样的, 但是可以发现, 代理类中没有保存业务实现类对象, 而是保口对象,虽然接口不能直接生成对象, 但接口可以保存子类对象, 换句话说, 代理类中的Subject 对象, 是可以保存任何实现了此接口的子类, 当我们需要代理一个子类时, 只需要将子类传给代理类, 就能代理这个类的方法,这样是省去了静态代理中的很多繁琐操作, 并且诸如一些操作: 日志操作, 安全管理, 权限管理...etc都可以在代理类中的invoke方法中实现, 当想记录某个业务逻辑的上述操作, 只需要实现Subject接口,然后传入代理类中就可以实现, 达到了高可用性,并且低耦合, 不会影响到业务逻辑. 非常实用.动态代理也是作为Spring AOP思想的基础,理解动态代理才能更好的理解AOP思想.与君共勉.






原创粉丝点击