设计模式之动态代理(JDK代理)

  动态代理跟静态代理一个很重要的区别在于,动态代理是在内存是中的,是在代码编译期后在内存是实现的,而静态代理是我们自己编写代理类,编译后生成class文件。动态代理需要借助两个类:java.lang.reflect.InvocationHandler和java.lang.reflect.Proxy。我们还是以上边的例子来实现动态代理。首先需要创建一个类,并实现java.lang.reflect.InvocationHandler接口

  • java.lang.reflect.Proxy:生成动态代理类和对象;
  •  java.lang.reflect.InvocationHandler(处理器接口):可以通过invoke方法实现 

接口:Subject.java

**
 * @author aaron
 */
public interface Subject {
    public int sellBooks();

    public String speak();
}

 真实对象:RealSubject.java

/**
 * @author aaron
 */
public class RealSubject implements Subject{
    @Override
    public int sellBooks() {
        System.out.println("卖书");
        return 1 ;
    }

    @Override
    public String speak() {
        System.out.println("说话");
        return "张三";
    }
}

处理器对象:MyInvocationHandler.java

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 定义一个处理器
 * 
 * @author aaron
 */
public class MyInvocationHandler implements InvocationHandler {
    /**
     * 因为需要处理真实角色,所以要把真实角色传进来
     */
    Subject realSubject;

    public MyInvocationHandler(Subject realSubject) {
        this.realSubject = realSubject;
    }

    /**
     *
     * @param proxy
     *            代理类
     * @param method
     *            正在调用的方法
     * @param args
     *            方法的参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("在被代理类之前做事情");
        // 类似于Spring AOP 中的@Before
        Object invoke = (int) method.invoke(realSubject, args);
        // 类似于Spring AOP 中的@after
        System.out.println("在被代理类之后做事情");
        return invoke;
    }

}

测试类:Client.java

import java.lang.reflect.Proxy;

/**
 * 调用类
 * @author aaron
 */
public class Client {
    public static void main(String[] args) {
        //真实对象
        Subject realSubject =  new RealSubject();

        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(realSubject);
        //代理对象
        Subject proxyClass = (Subject) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Subject.class}, myInvocationHandler);

        proxyClass.sellBooks();

        proxyClass.speak();
    }
}

 

posted @ 2019-04-25 13:39  crazy_boy  阅读(192)  评论(0编辑  收藏  举报