/* 步骤: * 1、编写主题接口(和静态代理一样) * 2、编写被代理类(和静态代理一样) * 3、编写代理工作处理器:即代理类要替被代理类做什么事情
* * 要求:必须实现InvocationHandler,重写 * Object invoke(Object proxy, Method method, Object[] args) * 第一个参数:代理类对象 * 第二个参数:被代理类和代理类 要执行的方法 * 第三个参数:要执行方法的实参列表 * * 这个invoke方法不是程序员调用,当代理类对象执行对应的代理方法时,自动调用的 * * 4、创建代理类及其对象 * 需要:Proxy:提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。 * * static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) * 第一个参数:被代理类的类加载器,我们希望被代理和代理类使用同一个类加载器 * 第二个参数:被代理类实现的接口们 * 第三个参数:代理工作处理器对象 * * 5、调用被代理的方法 */
/*主题接口*/ public interface TestDao { public abstract void demo01(); } /*这是被代理类*/ public class HelloTestDao implements TestDao { @Override public void demo01() { System.out.println("这是被代理类的方法"); } } /*代理工作处理器:即代理类要替被代理类做什么事情*/ //需求:必须重写invocationHandler public class ProxyInvocationHandler implements InvocationHandler { //声明被代理类的引用 private Object target; //重写构造方法 public ProxyInvocationHandler(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //这个invoke方法不是程序员调用,当代理类对象执行对应的代理方法时,自动调用的 //编写代理类要替被代理类做的事情 //1:获取当前时间 long start = System.currentTimeMillis(); //被代理对象的方法调用 Object invoke = method.invoke(target, args); long end = System.currentTimeMillis(); System.out.println(method.getName() + "方法运行时间:" + (end-start)); return invoke; } } public class TestProxy3 { public static void main(String[] args) { //1:创建被代理类对象 HelloTestDao helloTestDao = new HelloTestDao(); //2:获取被代理类的类加载器对象 ClassLoader classLoader = helloTestDao.getClass().getClassLoader(); //3:获取被代理类实现的接口 Class<?>[] interfaces = helloTestDao.getClass().getInterfaces(); //4:创建代理工作处理器对象 ProxyInvocationHandler proxyInvocationHandler = new ProxyInvocationHandler(helloTestDao); //5:创建代理对象,使用Proxy,创建动态代理类 //proxyInstance是代理类的对象,是编译器自动生成的一个类,因此叫动态代理 Object proxyInstance = Proxy.newProxyInstance(classLoader, interfaces, proxyInvocationHandler); //6:强转代理对象 TestDao testDao = (TestDao) proxyInstance; testDao.demo01(); } }