Solon2 开发之容器,八、动态代理的本质
在 Java 里动态代理,主要分:接口动态代理 和 类动态代理。因为它的代理类都是动态创建的,所以名字里会带上“动态”。
官网的有些地方叫“代理”,也有些地方叫“动态代理”。都是一个意思。
1、接口动态代理
这是 jdk 直接支持的能力。内在的原理是:框架会动态生成目标接口的一个代理类(即接口的实现类)并返回,使用者在调用接口的函数时,实际上调用的是这个代理类的函数,而代理类又把数据转给了调用处理器接口。
而整个过程的感受是调用目标接口,最终到了 InvocationHandler 的实现类上:
//1. 定义目标接口
public interface UserService{
void addUser(int userId, String userName);
}
//=>
//2. 通过JDK接口,获得一个代理实例
UserService userService = Proxy.getProxy(UserService.class, new InvocationHandlerImpl());
//生成的 UserService 代理类,差不多是这个样子:
public class UserService$Proxy implements UserService{
final InvocationHandler handler;
final Method addUser2; //示意一下,别太计较它哪来的
public UserService$Proxy(InvocationHandler handler){
this.handler = handler;
}
@Override
public void void addUser(int userId, String userName){
handler.invoke(this, addUser2, new Object[](userId, userName));
}
}
//在调用 userService 时,本质是调用 UserService$Proxy 的函数,最终又是转发到 InvocationHandler 的实现类上。
//=>
//3. 实现调用处理器接口
public class InvocationHandlerImpl implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
//...
}
}
一般,接口动态代理是为了:转发处理。
2、类动态代理
类的动态代理,略麻烦些,且要借助字符码工具框架(Solon 用的是 ASM)。内在的原理倒是相差不大:框架会动态生成目标类的一个代理类(一个重写了所有函数的子类)并返回,使用者在调用目标类的函数时,实际上调用的是这个代理类的函数,而代理类又把数据转给了调用处理器接口。调用处理器在处理时,会附加上别的处理。
而整个过程的感受是调用目标类,可以附加上很多拦截处理:
//1. 定义目标类
public class UserService{
public void addUser(int userId, String userName){
//..
}
}
//=>
//2. 通过框架接口,获得一个代理实例(::注意这里的区别!)
UserService userService = new UserService();
userService = AsmProxy.getProxy(UserService.class, new AsmInvocationHandlerImpl(userService));
//生成的 UserService 代理类,差不多是这个样子:
public class UserService$AsmProxy extends UserService{
final AsmInvocationHandler handler;
final Method addUser2; //示意一下,别太计较它哪来的
public UserService$Proxy(AsmInvocationHandler handler){
this.handler = handler;
}
@Override
public void void addUser(int userId, String userName){
handler.invoke(this, addUser2, new Object[](userId, userName));
}
}
//本质还是调用 UserService$AsmProxy 的函数,最终也是转发到 AsmInvocationHandler 的实现类上。
//=>
//3. 实现调用处理器接口
public class AsmInvocationHandlerImpl implements AsmInvocationHandler{
//::注意这里的区别
final Object target;
public AsmInvocationHandlerImpl(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
//::注意这里的区别
MethodWrap methodWrap = MethodWrap.get(method);
//MethodWrap 内部对各种拦截器做了封装处理
methodWrap.invoke(target, args);
}
}
一般,类动态代理是为了:拦截并附加处理。
3、关于 Solon 的类代理情况与“函数环绕拦截”
对 Solon 来讲,只有一个函数反射后再经 MethodWrap 执行的,就是被代理了。所有的“函数环绕拦截”处理就封装在 MethodWrap 里面。
- @Controller、@Remoting 注解的类
这两个注解类,没有 ASM 的类代码,但是它们的 Method 会转为 MethodWrap ,并包装成 Action 注册到路由器。即它们是经 MethodWrap 再调用的。所以它们有代理能力,支持“函数环绕拦截”。
- @Service、@Dao、@Repository 注解的类
这三个注解,来自 solon.aspect 插件包,它们注解的类,都会被 ASM 代理。跟上面原理分析的一样,也支持“函数环绕拦截”。
- 有克制的拦截
Solon 不支持表达式的随意拦截,必须以注解为“切点”进行显示拦截。所以 Solon 不用为所有的 Bean 增加代理能力,按需添加即可。
Solon2 开发之容器,八、动态代理的本质的更多相关文章
- mybatis开发Dao的Mapper动态代理方式
1. 开发规范Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体跟Dao原始方法中接口实现类的方法相 ...
- java开发必学知识:动态代理
目录 1. 引言 2. 代理模式及静态代理 2.1 代理模式说明 2.2 静态代理 2.3 静态代理局限性 3. 动态代理 3.1 JAVA反射机制 3.2 JDK动态代理 3.2.1 JDK动态代理 ...
- 02.MyBatis在DAO层开发使用的Mapper动态代理方式
在实际开发中,Mybatis作用于DAO层,那么Service层该如何调用Mybatis Mybatis鼓励使用Mapper动态代理的方式 Mapper接口开发方法只需要程序员编写Mapper接口(相 ...
- 【Mybtais】Mybatis 插件 Plugin开发(一)动态代理步步解析
需求: 对原有系统中的方法进行'拦截',在方法执行的前后添加新的处理逻辑. 分析: 不是办法的办法就是,对原有的每个方法进行修改,添加上新的逻辑:如果需要拦截的方法比较少,选择此方法到是会节省成本.但 ...
- 深入理解Spring IoC容器和动态代理机制
Deployment期间验证 实现一: <bean id="theTargetBean" class="..."/> <bean id=&qu ...
- MyBatis开发Dao的原始Dao开发和Mapper动态代理开发
目录 咳咳...初学者看文字(Mapper接口开发四个规范)属实有点费劲,博主我就废了点劲做了如下图,方便理解: 原始Dao开发方式 1. 编写映射文件 3.编写Dao实现类 4.编写Dao测试 Ma ...
- 【Java EE 学习 50】【Spring学习第二天】【使用注解的DI实现】【spring中的继承】【动态代理伪hibernate实现】
一.使用注解的DI实现 1.@Resource 使用该注解能够实现引用型属性的DI实现,该注解能够根据属性名和属性类型自动给属性赋值.一般使用@Resource(name="student& ...
- spring5——Aop的实现原理(动态代理)
spring框架的核心之一AOP,面向切面编程是一种编程思想.我对于面向切面编程的理解是:可以让我们动态的控制程序的执行流程及执行结果.spring框架对AOP的实现是为了使业务逻辑之间实现分离,分离 ...
- .NET:动态代理的 “5 + 1” 模式
背景 什么叫“动态代理”,代理模式我们都知道,动态代理就是动态生成的代理(采用Emit). 重量级的ORM和IOC产品离不开动态代理,作为开发人员,多数情况不用关注动态代理的内部实现机制,但是了解其一 ...
- java:Spring框架2(bean的作用域,静态工厂和实例工厂,自动装配,动态代理)
1.bean的作用域,静态工厂和实例工厂: bean.xml: <?xml version="1.0" encoding="UTF-8"?> < ...
随机推荐
- 发布 .NET 7 MAUI / MAUI Blazor 应用到 Windows 应用商店
.NET MAUI 目前仅允许发布 MSIX 包. 创建签名证书发布到本地传送门 [https://www.cnblogs.com/densen2014/p/16567384.html] 使用 Vis ...
- Nginx重写功能(rewrite与location)
一.常用的Nginx 正则表达式 二.访问路由location 2.1location的分类 location 大致可以分为三类: 精准匹配:location = / {} 一般匹配:location ...
- 嵌入式-C语言基础:字符串拼接函数strcat
#include<stdio.h> #include <string.h> //实现字符串拼接 char * mystrcat(char * dest,char * src) ...
- mindxdl--common--logger.go
// Copyright (c) 2021. Huawei Technologies Co., Ltd. All rights reserved.// Package common the contr ...
- 注册IBMlinuxone并使用xshell登陆
登陆地址:https://linuxone.cloud.marist.edu/#/login 注册地址:https://linuxone.cloud.marist.edu/#/register?fla ...
- Windows 下 OpenSSH 安装使用
OpenSSH 是安全 Shell (SSH) 工具的开放源代码版本,Linux 及其他非 Windows 系统的管理员使用此类工具跨平台管理远程系统. OpenSSH 在 2018 年秋季已添加至 ...
- Kafka教程(三):原理及存储
一.思维导图 1.实时更新连接 https://www.mubucm.com/doc/1GRE2U7qYuj 2.思维导图图片 二.具体内容 8.系统架构 架构推导 拓扑结构 多对多 ...
- 【Hadoop学习】中:HDFS、shell操作、客户端API操作、数据流、1NN、2NN原理、DataNode配置
一.概述 1.背景.定义.使用场景(一次写入.不支持修改) 2.优(容错)缺点(延迟.不支持小文件.不支持修改) 3.组成架构 NameNode:Master,管理命名空间.配置策略 DataNode ...
- 干电池升压5V,功耗比较低
干电池升压5V,功耗10uA PW5100干电池升压5V芯片 输出电容: 所以为了减小输出的纹波,需要比较大的输出电容值.但是输出电容过大,就会使得系统的 反应时间过慢,成本也会增加.所以建议使用一个 ...
- 编程思想的转变 软件开发目录规范 collections、time、datetime、 random模块
目录 编程思想的转变 软件目录开发规范(重要) 内置模块:collections模块 简介 具名元组 namedtuple 实现二维坐标系 实现扑克牌 队列与堆栈 collection.deque() ...