动态代理
对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通过动态代理实现面向切面编程