动态代理模式使用初探

news/2024/7/4 10:00:46

jdk文档:

写道
动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。代理实例 是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。

 

测试代码如下:
一个接口:MyInterface

public interface MyInterface {
public void print();
public void test(int num);
}

 

实现以上接口的类:MyTest

public class MyTest implements MyInterface{
public void print(){
    System.out.println("MyTest print");
}
public void test(int num){
    System.out.println(num);
}
}

 


处理类:MyTestHandler

public class MyTestHandler implements InvocationHandler {

    private MyInterface mytest = null;

    public MyInterface bind(MyInterface test) { //注意传递的参数类型是接口,而不是实现类
        this.mytest = test;
        MyInterface proxyTest = (MyInterface) Proxy.newProxyInstance(test.getClass().getClassLoader(), test.getClass().getInterfaces(), this);
        return proxyTest;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //具体的处理策略,根据方法名判断
        Object obj = null;
        if ("print".equals(method.getName())) {
            System.out.println("got it");
        } else if ("test".equals(method.getName())) {
            int num = (Integer)args[0];
            System.out.println(num+2);
        } else {
            obj = method.invoke(mytest, args);  //交给目标对象处理
        }
        return obj;
    }
}

 

测试类:Main

public class Main {
public static void main(String args[]){
MyTest test = new MyTest();
MyTestHandler handler = new MyTestHandler();
MyInterface proxy = handler.bind(test);//绑定方法返回对象的代理,以后可以操作该代理,隐藏了实际的对象
proxy.test(3);
}
}
 



分析:
    通过对代理类的调用,代替了对实际类MyTest的调用,在invoke方法中,可以截获对方法的调用,针对特定的策略采取相应的措施。无需特殊处理的话,还是调用实际的对象的方法。

补充:
摘自jdk文档:

Proxy的静态方法:

写道
newProxyInstance
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader, interfaces).
getConstructor(new Class[] { InvocationHandler.class }).
newInstance(new Object[] { handler });
 

 


http://www.niftyadmin.cn/n/2864071.html

相关文章

深入浅出hibernate摘录2

以下内容摘自深入浅出hibernate 在编写代码的时候&#xff0c;尽量将POJO的getter/setter方法设定为public&#xff0c;如果设定为private&#xff0c;protected&#xff0c;hibernate将无法对属性的存取进行优化&#xff0c;只能转而采用传统的反射机制进行操作&#xff08;hi…

区分运行时异常和编译时异常

jianchen 写道当你确信方法的使用者会处理你的方法抛出的异常时&#xff0c;可以使用编译时异常。不处理编译时异常&#xff0c;程序编译不能通过。而运行时异常给了方法的调用者以选择&#xff0c;他可以选择处理&#xff0c;也可以不处理。处理的话&#xff0c;进行catch即可…

hibernate 学习之第六篇

基于主键的一对一关联 Person类和IdCard&#xff0c;一对一映射。 person的属性为&#xff1a;id&#xff0c;name&#xff0c;idCard IdCard的属性为&#xff1a;id&#xff0c;usefulLife&#xff0c;person 由于身份证和人是一对一的&#xff0c;身份证的id和人的id可以相同…

hibernat学习之第七篇

多对多关联关系的映射 在操作和性能方面都不太理想&#xff0c;所以多对多的映射使用较少&#xff0c;实际使用中最好转换成一对多的对象模型&#xff1b;hibernate会为我们创建中间关联表&#xff0c;转换成两个一对多。 核心配置&#xff1a; <set name"ss" t…

Redis——基于主从复制实现高可用(redis-sentinel)

一.sentinel哨兵模式介绍 Sentinel(哨兵)是用于监控redis集群中Master状态的工具&#xff0c;是Redis 的高可用性解决方案&#xff0c;sentinel哨兵模式已经被集成在redis2.4之后的版本中。sentinel是redis高可用的解决方案&#xff0c;sentinel系统可以监视一个或者多个redis …

hibernate学习之第八篇

组件映射 关联的属性是个复杂类型的持久化类&#xff0c;但不是实体即&#xff1a;数据库中没有表与该属性对应&#xff0c;但该类的属性要持久保存的。 对于单表的对象细分&#xff0c;在hibernate中可借助Component节点的定义完成。 何谓Component&#xff1f;从名字上来看&…

hibernate学习之第九篇

hibernate中的集合类型 引入&#xff1a; Hibernate可以持久化以下java集合的实例, 包括java.util.Map, java.util.Set, java.util.SortedMap, java.util.SortedSet, java.util.List, 和任何持久实体或值的数组。类型为java.util.Collection或者java.util.List的属性还可以使用…

Redis——集群方案之redis cluster的搭建部署

一.redis的集群之redis cluster的概念 对于Redis集群方案有好多种&#xff0c;基本常用的就是twemproxy&#xff0c;codis&#xff0c;redis cluster这三种解决方案。 本文介绍redis cluster。 上篇博文实现redis的高可用&#xff0c;针对的主要是master宕机的情况&#xff…