资讯专栏INFORMATION COLUMN

Proxy invocationHandler

terasum / 1280人阅读

摘要:动态代理即,动态代理是利用反射技术,在运行时创建一个实现某些给定接口的新类。调用该方法调用类中的,参数为空的方法。

动态代理

即,动态代理是利用java反射技术,在运行时创建一个实现某些给定接口的新类。

栗子

先定义接口

public interface people {
    public String work();
}

实现该接口

public class Teacher implements people{

    @Override
    public String work() {
        System.out.println("教书育人");
        return "教书";
    }
}

编写代理类

import com.sun.xml.internal.ws.api.pipe.FiberContextSwitchInterceptor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class WorkHandler implements InvocationHandler {
    // 代理类的对象
    private Object obj;

    public WorkHandler(){

    }

    // 在调用这个方法的时候,会被调度到invoke方法,并将参数传入
    public WorkHandler(Object obj){
        this.obj = obj;
    }
    // 在调用给类的方法的时候,会被调度到invoke方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 真实对象执行之前添加操作
        // 调用obj类的method方法,并且参数为args
        Object invoke = method.invoke(obj, args);
        // 真实对象执行后添加操作
        return invoke;// 返回执行的结果
    }
}

最后运行

import java.io.FileInputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Main {
    public static void main(String[] args){
        // 要代理的对象
        people people = new Teacher();  // 创建要代理的真实对象
        // 进行注册
        InvocationHandler handler = new WorkHandler(people);
        // 进行创建代理对象
        // 定义一个代理对象
        people proxy;
        // 调用Proxy.newProxyInstance方法
        // 需要传入真实对象实现的接口,为下一步调用该方法做准备
        // 将handler关联到invocationHandler对象,用于调度到invoke方法
        // 由于返回的对象为object类型,需要进行强制类型转换,保留people接口定义的方法
        // 最后一个参数要对对象进行关联,最后批量生产出对象
        proxy = (people) Proxy.newProxyInstance(handler.getClass().getClassLoader(), people.getClass().getInterfaces(), handler);
        System.out.println(proxy.work());
    }
}
第一个参数

第一个参数是运行时,创建的代理对象。

反射+IO操作读取class文件
import java.io.FileInputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main {
    // 需要使用static让其加载进入内存
    static class myClassLoader extends ClassLoader{
        private String classPath;  // 获取当前类的在磁盘中保存的地址
        // 通过构造函数将地址注入
        public myClassLoader(String classPath){
            this.classPath = classPath;
        }
        // 将文件内容加载进入内存
        private byte[] loadByte(String name) throws Exception{
            // 获取一个输入流,
            FileInputStream fis = new FileInputStream(classPath + "/" + name + ".class");
            // 获取长度
            int len = fis.available();
            // 定义byte数组
            byte[] data = new byte[len];
            // 加载进入内存
            fis.read(data);
            // 关闭流
            fis.close();
            return data;
        }
        // 重写findClass方法,让加载的时候调用findClass方法
        protected Class findClass(String name) throws ClassNotFoundException{
            try{
                // 读取文件到数组中
                byte[] data = loadByte(name);
                // 将字节码加载进入内存当中
                return defineClass(name, data, 0, data.length);
            }catch(Exception e){
                e.printStackTrace();
            }
            return null;
        }
    }
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
        // 先初始化该类
        myClassLoader classLoader = new myClassLoader("/home/ming");
        // 此时会调用findClass加载Test.class加载进入内存当中
        Class clazz = classLoader.loadClass("com.ming.Test");
        // 实例化该类对象
        Object obj = clazz.newInstance();
        // 获取clazz该类方法中名称为hello,参数为空的方法。
        Method helloMethod = clazz.getDeclaredMethod("helloWorld", null);
       // 调用该方法
        // 调用obj类中的helloMethod,参数为空的方法。
       helloMethod.invoke(obj, null);
    }
}

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73124.html

相关文章

  • Java动态代理之InvocationHandler最简单的入门教程

    摘要:网上关于的动态代理,和这些概念有讲解得非常高深的文章。现在咱们通过一个最简单的例子认识什么是。创建一个简单的类,实现这个接口。看看用如何优雅实现吧希望这个例子能让大家对的动态代理之有了最基本的了解。 网上关于Java的动态代理,Proxy和InvocationHandler这些概念有讲解得非常高深的文章。其实这些概念没有那么复杂。现在咱们通过一个最简单的例子认识什么是Invocatio...

    lingdududu 评论0 收藏0
  • Java动态代理之InvocationHandler最简单的入门教程

    摘要:网上关于的动态代理,和这些概念有讲解得非常高深的文章。现在咱们通过一个最简单的例子认识什么是。创建一个简单的类,实现这个接口。看看用如何优雅实现吧希望这个例子能让大家对的动态代理之有了最基本的了解。 网上关于Java的动态代理,Proxy和InvocationHandler这些概念有讲解得非常高深的文章。其实这些概念没有那么复杂。现在咱们通过一个最简单的例子认识什么是Invocatio...

    Joonas 评论0 收藏0
  • Java 动态代理(Dynamic proxy) 小结

    摘要:代理模式基本概念不论是静态代理还是动态代理其本质都是代理模式的一种实现那么什么是代理模式呢代理模式即给某一个对象提供一个代理并由代理对象控制对原对象的引用代理模式其实取材于实际生活例如我们生活中常见的房屋租赁代理我们在租房时一般不是直接和房 代理模式 基本概念 不论是静态代理还是动态代理, 其本质都是代理模式的一种实现, 那么什么是代理模式呢?代理模式, 即给某一个对象提供一个代理, ...

    Jason 评论0 收藏0
  • 慕课网_《模式的秘密之代理模式》学习总结

    时间:2017年08月28日星期一说明:本文部分内容均来自慕课网。@慕课网:http://www.imooc.com教学源码:https://github.com/zccodere/s...学习源码:https://github.com/zccodere/s... 第一章:代理模式 1-1 概念介绍 学习本课程基础 面向对象的设计思维 了解多态的概念 了解反射机制 课程目标 代理模式基本概念及分类...

    wow_worktile 评论0 收藏0
  • Spring AOP(二) 修饰者模式和JDK Proxy

    摘要:修饰者模式设计模式中的修饰者模式能动态地给目标对象增加额外的职责。修饰者模式调用的时序图如下图所示。的实现原理和修饰者模式类似。  在上边一篇文章中我们介绍了Spring AOP的基本概念,今天我们就来学习一下与AOP实现相关的修饰者模式和Java Proxy相关的原理,为之后源码分析打下基础。 修饰者模式  Java设计模式中的修饰者模式能动态地给目标对象增加额外的职责(Respon...

    Jackwoo 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<