核心API
InvocationHandler接口
该接口叫做调用处理器,该接口只有一个抽象方法:invoke()。
在InvocationHandler接口的实现类中,实现调用目标方法并增强功能的语句就写在invoke()方法里。
public Object invoke(Object proxy, Method method, Object[] args)
- proxy:代表生成的代理对象
- method:代表目标方法
- args:代表目标方法的参数
这三个参数都是jdk运行是赋值的,无需程序员给出。
Method类
InvocationHandler接口的invoke()方法中,第二个参数就是Method类对象,该类中也有一个invoke()方法,可以调用目标方法。这两个invoke()方法虽然同名,但是没有关系。
public Object invoke(Object obj, Object… args)
调用执行obj对象所属类的方法,该方法由调用者Method对象确定。在代码中,一般写法为:
method.invoke(target,args);
其中,method是InvocationHandler接口invoke方法的第二个参数。
Proxy类
通过JDK的java.lang.reflect.Proxy类实现动态代理,会使用其静态方法
newProxyInstance()
,根据目标对象、业务接口以及调用处理器,自动生成一个动态代理对象。
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
- loader:目标类的类加载器,通过目标对象的反射可以获取【目标对象.getClass().getClassLoader()】
- interfaces:目标类实现的接口数组,同样可以通过目标对象的反射获取【目标对象.getClass().getInterfaces()】
- h:调用处理器,也就是InvocationHandler接口实现类对象
动态代理实现步骤
- 创建目标接口,定义目标类要完成的功能
- 创建目标类来实现目标接口
- 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能 3.1 调用目标类的方法 3.2 增强功能
- 使用Proxy类的静态方法,创建代理对象。并把返回值也就是代理对象转为接口类型。
示例
第一步:定义目标接口
publicinterfaceService{intinsert();}
第二步:目标类
publicclassUserServiceimplementsService{@Overridepublicintinsert(){System.out.println("insert user");return1;}}
第三步:代理类
publicclassServiceProxyimplementsInvocationHandler{privateObject target;publicServiceProxy(Object target){this.target = target;}@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{System.out.println("前置增强");Object res = method.invoke(target, args);System.out.println("后置增强");return res;}}
测试代码
publicstaticvoidmain(String[] args){Service service =newUserService();ServiceProxy serviceProxy =newServiceProxy(service);Service proxy =(Service)Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(),serviceProxy);
proxy.insert();}
结果:
重构
第一步:代理类中添加生成代理对象的方法
最终代理类代码如下:
publicclassServiceProxyimplementsInvocationHandler{privateObject target;publicServiceProxy(Object target){this.target = target;}@OverridepublicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{System.out.println("前置增强");Object res = method.invoke(target, args);System.out.println("后置增强");return res;}publicObjectgetProxy(){returnProxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);}}
第二步:目标工厂
publicclassServiceFactory{publicstaticObjectgetService(Object service){returnnewServiceProxy(service).getProxy();}}
测试代码
publicstaticvoidmain(String[] args){Service userService =(Service)ServiceFactory.getService(newUserService());
userService.insert();}
结果:
版权归原作者 梁云亮 所有, 如有侵权,请联系我们删除。