动态代理
1.动态代理和静态代理的角色是一样的
这里就不在赘述了,看上一篇静态代理就行。
2.动态代理的代理类是动态生成的
3.分为两类-----类基于接口动态代理和基于类的动态代理
a)基于接口动态代理---JDK动态代理
b)基于类的动态代理---cglib
现在javasist来生成动态代理
4.JDK动态代理--Proxy类和InvocaHandler接口
InvocationHandler是代理实例的调用处理程序实现的接口
每个代理实例都具有一个关联的调用处理程序,对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法
Object invoke(Object proxy,Method method,Object[] args) //在代理实例上处理方法调用并返回结果
在代理实例上处理方法调用并返回处理结果。在与方法关联的代理实例上调用方法时,将在调用处理程序上调用此方法。
参数:
proxy:在其上调用方法的处理实例
method:对应于在代理实例上调用的接口方法的Method实例。Method对象的声明类将是在其中声明方法的接口,该接口可以是代理类依赖继承方法的代理接口的超接口。
args:包含传入代理实例上方法的调用的参数值的对象数组,如果接口方法不使用参数,则为null。基本类型的参数被包装在适当基本包装器类(如:java.lang.Intefer或java.lang.Boolean)的实例中
返回:
从代理实例 的方法调用返回的值。如果接口方法的声明返回类型是基本类型,则此方法返回的值一定是相应基本包装对象类的实例;否则,它一定是可分配到声明返回类型的类型。如果此方法返回的值为null并且接口方法返回的类型是基本类型,则代理实例上的方法调用将抛出NullPointException。否则,如果此方法返回的值与上述接口方法的声明返回类型不兼容,则代理实例上的方法调用将抛出ClassCastException。
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
static Object newProxyInstance(ClassLoader lodaer,Class<?> interfaces,InvocationHandler h)
返回一个指定接口的代理类实例,=该接口可以将方法调用指派到指定的调用处理程序。此方法相当于:
Proxy.getProxyClass(loader,interfaces). getConstructor(new Class[] {InvocationHandler.class}). newInstance(new Object[]{handler});
Proxy.newProxyInstance抛出IllegalArgumentException,原因与Proxy.getProxyClass相同。
参数:
loader --定义代理类的类加载器
interfaces --代理类要实现的接口列表
h -指派方法调用的调用处理程序
5.实现:
接下来感受一下动态代理
UserService.java接口类
public interface UserService {
public void add();
public void delete();
public void update();
public void search();
}
UserServiceImpl.java实现类
public class UserServiceImpl implements UserService{
public void add() {
System.out.println("增加用户...................");
}
public void delete() {
System.out.println("删除用户...................");
}
public void update() {
System.out.println("更新用户...................");
}
public void search() {
System.out.println("查询用户...................");
}
}
创建一个代理类
public class ProxyInovationHandler implements InvocationHandler{
//target 依赖目标 要代理的事务
private Object target;
public void setRent(Object target) {
this.target = target;
}
/**
* 生成代理类
* */
public Object getProxy(){
return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
}
/**
* proxy是代理类
* method代理类的调用处理程序的方法对象
* */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
log(method.getName());
Object result=method.invoke(target, args);
return result;
}
public void log(String methodName){
System.out.println("执行"+methodName+"方法...................");
}
}
UserClient.java
public class UserClient {
public static void main(String[] args) {
UserService userService=new UserServiceImpl();
ProxyInovationHandler pih=new ProxyInovationHandler();
pih.setTarget(userService);
UserService proxy=(UserService) pih.getProxy();
proxy.delete();
}
}
仔细敲完几遍代码并体会代理的感觉,可以得出,只要有接口类和实现方法,就可以让代理类去执行
public class ListTest {
public static void main(String[] args) {
ProxyInovationHandler pih=new ProxyInovationHandler();
pih.setTarget(new ArrayList());
List list=(List) pih.getProxy();
list.add("你好");
list.add("嗯嗯");
}
}
若还有不太懂的可以的看视频:链接:https://pan.baidu.com/s/1cK4cryW08KlRt2TriGoPIw
提取码:xud4
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 提示词工程——AI应用必不可少的技术
· 地球OL攻略 —— 某应届生求职总结
· 字符编码:从基础到乱码解决
· SpringCloud带你走进微服务的世界