Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类。如果我们在程序中为一个或多个接口动态地生成实现类,就可以使用Proxy来创建动态代理类;如果需要为一个或多个接口动态的创建实例,也可以使用Proxy来创建动态代理实例。
Proxy提供了如下两个方法来创建动态代理类和动态代理类:
(1)、static Class<?> getProxyClass(ClassLoader loader,Class<?> ...interfaces) : 创建一个动态代理类所对应的Class对象,该代理类将实现interfaces所指定的多个接口。第一个ClassLoader指定生成动态代理类的类加载器。
(2)、static Object newProxyInstance(ClassLoader loader,Class<?> interfaces, InvocationHandler h) :直接创建一个动态代理对象,该代理对象的实现类实现了interfaces指定的系列接口,执行代理对象的每个方法时都会被替换成执行 InvocationHandler对象的invoke方法。
实际上,即使采用第一种方式获取了一个动态代理类之后,当程序需要通过该代理类来创建对象时一样需要传入一个InvocationHandler对象。也就是说,系统生成的每个代理对象都有一个与之关联的InvocationHandler对象。
下面是AOP动态代理的实现:
在方法前后加入一写通用方法,比如项目中的日志记录。
Dog.java
package com.reflect.proxy; public interface Dog { public void info(); public void run(); }GunDog.java
package com.reflect.proxy; public class GunDog implements Dog { @Override public void info() { System.out.println("我是一只猎狗"); } @Override public void run() { System.out.println("我奔跑迅速"); } }
DogUtil.java
package com.reflect.proxy; public class DogUtil { public void method1(){ System.out.println("=====模拟第1个通用方法======"); } public void method2(){ System.out.println("=====模拟第2个通用方法======"); } }借助于Proxy和InvocationHandler就可以实现:当程序调用info()方法和run()方法时,系统就可以“自动” 将method1()和method2() 两个通用方法插入info()和run()犯法
package com.reflect.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class MyInvocationHandler implements InvocationHandler { //需要被代理的对象 private Object target; public void setTarget(Object target){ this.target=target; } //指定动态代理的所有方法时,都会替换成执行如下的invoke方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { DogUtil du=new DogUtil(); //执行DogUtil中的method1 du.method1(); //以target为主掉来执行method方法 Object result=method.invoke(target, args); System.out.println(result); //执行DogUtil中的Method2 du.method2(); return result; } }
为指定的target生成代理类.
package com.reflect.proxy; import java.lang.reflect.Proxy; public class MyProxyFactory { //为指定target生成动态代理对象 public static Object getProxy(Object target){ MyInvocationHandler handler=new MyInvocationHandler(); //为MyInvotationHandler设置target对象 handler.setTarget(target); //创建并返回一个动态代理 return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), handler); } }
测试类
package com.reflect.proxy; public class Test { public static void main(String[] args) { //创建一个原始的GunDog对象,作为target Dog target=new GunDog(); //以指定的target创建动态代理 Dog dog=(Dog) MyProxyFactory.getProxy(target); dog.info(); dog.run(); } }
输出:
=====模拟第1个通用方法====== 我是一只猎狗 =====模拟第2个通用方法====== =====模拟第1个通用方法====== 我奔跑迅速 =====模拟第2个通用方法======