java中的动态代理

类加载器

类加载器作用:将加载进入内存
使用:对象.getClass().getClassLoader()
加载类型:

  • 引导类:JDK的核心类库(String,Object等)
  • 系统类:自己写的类
  • 扩展类:JDK的扩展类(lib/ext下的类)

静态代理

使用装饰者设计模式

pl:IO流中的缓冲流:BufferedRead必须依赖原有的IO对象,new BufferedReader(new FileReader)

实现装饰模式

  • 原有对象和装饰对象必须拥有相同的父类,或者相同的接口
  • 使用装饰对象必须将原有对象传递过来
  • 重写原来的方法,增强功能

动态代理

public static Object newProxyInstance(ClassLoader loader,
                                      Class<?>[] interfaces,
                                      InvocationHandler h)
                               throws IllegalArgumentException

返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。

参数:

  • loader - 被代理对象的类加载器
  • interfaces - 被代理对象实现的所有接口
  • h - 被创建出来的代理对象要做的事情
    返回:
    一个带有代理类的指定调用处理程序的代理实例,它由指定的类加载器定义,并实现指定的接口
//InvocationHandler接口的方法
Object invoke(Object proxy,
              Method method,
              Object[] args)
              throws Throwable

在代理实例上处理方法调用并返回结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。

参数:

  • proxy - 在其上调用方法的代理实例(被创建好的代理对象)
  • method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。(被代理对象执行的方法)
  • args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如 java.lang.Integer 或 java.lang.Boolean)的实例中。(被代理对象执行方法需要的参数)

例子

package com.ahu.proxyTest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * 实现动态代理
 * 被代理对象:ArrayList
 * 被代理方法:拒绝修改长度的方法如:add,addAll,remove
 *
 * 使用Proxy类创建一个代理对象
 */
public class proxyTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("jack");
        list.add("rose");

        //传递一个被代理对象,返回代理对象
        list = proxy(list);
//        list.add("abc");//以下使用的是代理方法invoke
        int size = list.size();
        System.out.println(size);
        System.out.println(list.get(0));
    }

    /**
     *
     * @param list 想要代理的对象
     */
    public static List<String> proxy(List<String> list){
        //工具类创建代理对象
        return (List<String>) Proxy.newProxyInstance(list.getClass().getClassLoader(), list.getClass().getInterfaces()
                , new InvocationHandler() {
                    /**
                     * 属于代理对象的方法,类比经纪人
                     * 只要使用了被代理对象的方法,并不会直接执行list的方法,而是执行invoke方法
                     * @param proxy 代理人对象
                     * @param method 被代理对象执行的方法
                     * @param args 方法的实际参数
                     * @return 被代理对象调用方法的返回值,list.size()返回int
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if(method.getName().equals("add")){
                            throw new RuntimeException("add禁止调用");
                        }
                        if(method.getName().equals("remove")){
                            throw new RuntimeException("remove禁止调用");
                        }
                        //其他方法可以调用
                        return method.invoke(list, args);
                    }
                });
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值