您当前的位置: 首页 > 

梁云亮

暂无认证

  • 4浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

JDK动态代理

梁云亮 发布时间:2022-04-19 14:48:38 ,浏览量:4

核心API InvocationHandler接口

该接口叫做调用处理器,该接口只有一个抽象方法:invoke()。 在InvocationHandler接口的实现类中,实现调用目标方法并增强功能的语句就写在invoke()方法里。

public Object invoke(Object proxy, Method method, Object[] args)

invoke()方法表示代理对象要执行的功能代码。

  • 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类的静态方法,创建代理对象。并把返回值也就是代理对象转为接口类型。
示例 第一步:定义目标接口
public interface Service {
    int insert();
}
第二步:目标类
public class UserService implements Service{
    @Override
    public int insert() {
        System.out.println("insert user");
        return 1;
    }
}
第三步:代理类
public class ServiceProxy implements InvocationHandler {
    private  Object target;

    public ServiceProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置增强");
        Object res = method.invoke(target, args);
        System.out.println("后置增强");
        return res;
    }
}
测试代码
public static void main(String[] args) {
    Service service = new UserService();
    ServiceProxy serviceProxy = new ServiceProxy(service);
    Service proxy = (Service) Proxy.newProxyInstance(service.getClass().getClassLoader(), service.getClass().getInterfaces(),serviceProxy);
    proxy.insert();
}

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

重构 第一步:代理类中添加生成代理对象的方法

最终代理类代码如下:

public class ServiceProxy implements InvocationHandler {
    private  Object target;

    public ServiceProxy(Object target) {
        this.target = target;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("前置增强");
        Object res = method.invoke(target, args);
        System.out.println("后置增强");
        return res;
    }

    public Object getProxy(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }
}
第二步:目标工厂
public class ServiceFactory {
    public static Object getService(Object service){
        return new ServiceProxy(service).getProxy();
    }
}
测试代码
public static void main(String[] args) {
    Service userService = (Service) ServiceFactory.getService(new UserService());
    userService.insert();
}

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

关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0825s