0


JDK动态代理

核心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接口实现类对象

动态代理实现步骤

  1. 创建目标接口,定义目标类要完成的功能
  2. 创建目标类来实现目标接口
  3. 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能 3.1 调用目标类的方法 3.2 增强功能
  4. 使用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();}

结果:
在这里插入图片描述

标签: JDK动态代理

本文转载自: https://blog.csdn.net/lianghecai52171314/article/details/124273340
版权归原作者 梁云亮 所有, 如有侵权,请联系我们删除。

“JDK动态代理”的评论:

还没有评论