【Java】动态代理

动态代理

对Collection接口进行代理,以前的remove(Object obj)方法是删除集合中第一次出现的元素

(比如集合中有多个“abc”,调用remove(“abc”)后只会删除第一个元素)。

代理后,要求在调用remove(Object obj)方法后,能够删除集合中所有匹配的元素。

使用步骤:

1.判断是否需要请求代理

2.如果需要,确定请代理的位置

3.使用Proxy调用newProxyInstance方法,得到代理对象

4.对得到的代理对象进行向下转型----转换成接口类型--->因为生成的代理对象一定实现了和被代理类相同的接口

5.为newProxyInstance方法传实际参数

6.在InvocationHandler的invoke方法里面,书写代理对象调用方法需要执行的代码
// 创建ArrayList集合,限制集合元素的类型为String类型
// 添加元素
// 获得被代理类的类加载器
// 获得被代理类实现的所有接口的Class对象
// 创建事件处理接口对象

// 代理对象只要调用方法就会来到这里
// 参数1: 代理对象(慎用)
// 参数2: 代理对象调用的方法
// 参数3: 代理对象调用方法时传入的实际参数
// 返回值: 代理对象调用方法的返回值
// 通过反射执行代理对象调用的方法---被代理对象
// 判断代理对象调用的方法是否是remove方法
// 如果是书写remove方法需要执行的代码---增强
// 获取list集合的迭代器
// 迭代
// 集合元素
// 判断元素是否是abc
// 相等,就删除
// 判断代理对象调用的方法是否是set方法
// 增强set方法的代码
// 代理对象调用方法的返回值
package com.jcli.demo06_动态代理;

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

public class Test07 {
    public static void main(String[] args) {
        // 创建ArrayList集合,限制集合元素的类型为String类型
        ArrayList<String> list = new ArrayList<>();
        // 添加元素
        list.add("abc");
        list.add("bac");
        list.add("nba");
        list.add("abc");
        list.add("abc");
        // 获得被代理类的类加载器
        ClassLoader classLoader = list.getClass().getClassLoader();
        // 获得被代理类实现的所有接口的Class对象
        Class<?>[] interfaces = list.getClass().getInterfaces();
        // 创建事件处理接口对象
        InvocationHandler ih = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // 代理对象只要调用方法就会来到这里
                // 参数1: 代理对象(慎用)
                // 参数2: 代理对象调用的方法
                // 参数3: 代理对象调用方法时传入的实际参数
                // 返回值: 代理对象调用方法的返回值
                // 通过反射执行代理对象调用的方法---被代理对象
                Object res = method.invoke(list, args);
                // 判断代理对象调用的方法是否是remove方法
                if (method.getName().equals("remove")) {
                    // 如果是书写remove方法需要执行的代码---增强
                    // 获取list集合的迭代器
                    Iterator<String> it = list.iterator();
                    // 迭代
                    while (it.hasNext()) {
                        // 集合元素
                        String e = it.next();
                        // 判断元素是否是abc
                        if (e.equals(args[0])) {
                            // 相等,就删除
                            it.remove();
                        }
                    }
                }
                // 判断代理对象调用的方法是否是set方法
                if(method.getName().equals("set")){
                    // 增强set方法的代码
                }
                // 代理对象调用方法的返回值
                return res;
            }
        };

        // 获得ArrayList类的代理对象
        List<String> proxy = (List<String>) Proxy.newProxyInstance(classLoader, interfaces, ih);
        System.out.println("未删除"+list);
        // 请代理调用remove方法,删除abc元素
        boolean res1 = proxy.remove("abc");
        System.out.println("res1:"+res1);// res1: true
        System.out.println("删除后:" + list);// 删除前:[bac, nba]
        // 请代理调用remove方法,删除bac元素
        boolean res2 = proxy.remove("bac");
        System.out.println("res2:"+res2);// res1: true
        System.out.println("删除后:" + list);// 删除前:[nba]

        // 请代理调用remove方法,删除abn元素
        boolean res3 = proxy.remove("abn");
        System.out.println("res3:"+res3);// res1: false
        System.out.println("删除后:" + list);// 删除前:[nba]
        // 请代理调用 E set(int index, E element);方法
        String setE = proxy.set(0, "cba");
        System.out.println("被替换的元素:"+setE);// 被替换的元素:nba
        System.out.println("替换后:"+list);// 替换后:[cba]
        // 请代理调用 size方法----不需要增强
        int size = proxy.size();
        System.out.println(size);// 1
        // 不请代理调用remove方法,删除abc元素
        //list.remove("abc");
        //System.out.println("删除后:" + list);// 删除前:[bac, nba, abc, abc]
    }
}

spring通过动态代理实现面向切面编程

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值