proxy代理实现接口调用处理
proxy代理实现接口调用处理
我们知道,要调用接口必须要实例化才能调用。
那么我们能不能不实例化调用呢?像mybatis、hibernate那样定义一个接口就能注入调用。其实他们的底层实现就是用代理模式 proxy:
在不实例化的情况下调用接口(实际上代理实例化了)
首先定义一个注解用来区别
import java.lang.annotation.*;
/**
* @author lingkang
* Created by 2022/5/4
* mapper 查询注解
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Select {
/**
* 查询语句 SQL
*/
String value() default "";
}
再编写一个调用接口
import java.util.Map;
/**
* @author lingkang
* Created by 2022/5/4
*/
public interface MyMapper {
@Select("select * from user where id=?")
Map select(Integer id);
}
然后定义代理调用处理类
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.HashMap;
import java.util.Map;
/**
* @author lingkang
* Created by 2022/5/4
*/
public class MyInvocationHandler implements InvocationHandler, Serializable {
private Class<?> clazz;
public MyInvocationHandler(Class<?> clazz) {
this.clazz = clazz;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Method exMethod = clazz.getMethod(method.getName(), getClassTypes(args));
if (args[0].getClass().isArray()) {
args = (Object[]) args[0];
if (args.length == 0)
args = null;
}
Select select = exMethod.getAnnotation(Select.class);
System.out.println("查询SQL:" + select.value());
System.out.println("参数: " + args[0]);
// 接口需要返回的结果类型
//Class<?> returnType = exMethod.getReturnType();
Class<?> returnType = getReturnType(exMethod);
System.out.println("接口需要返回的结果类型: " + returnType);
Map map = new HashMap();
map.put("result", "hello lingkang!");
System.out.println("假设在此执行SQL返回结果:");
return map;
}
// 有时可能需要特殊处理
public static Class<?> getReturnType(Method method) {
Type returnType = method.getGenericReturnType();
if (returnType instanceof ParameterizedType) {
ParameterizedType type = (ParameterizedType) returnType;
return (Class<?>) type.getActualTypeArguments()[0];
} else if ("void".equals(returnType.getTypeName())) {
return null;
}
return Map.class;
}
public static Class<?>[] getClassTypes(Object[] args) {
Class[] clazz = new Class[args.length];
for (int i = 0; i < args.length; i++)
clazz[i] = args[i].getClass();
return clazz;
}
}
调用这个代理处理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* @author lingkang
* Created by 2022/5/4
*/
public class Demo01 {
public static void main(String[] args) {
// 获取接口代理
MyMapper mapper = getMapper(MyMapper.class, new MyInvocationHandler(MyMapper.class));
// 调用
System.out.println("调用结果:"+mapper.select(1));
}
/**
* 代理实例化
*/
public static <T> T getMapper(Class<T> clazz, InvocationHandler handler) {
return (T) Proxy.newProxyInstance(
clazz.getClassLoader(),
new Class[]{clazz},
handler);
}
}
结果:
proxy代理实现接口调用处理的更多相关文章
- requests使用“proxy”代理访问接口
在requests中使用proxy代理访问 使用前先更新requests版本为支持socks的版本. 先pip安装对应库: >> pip install -U requests[so ...
- SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架
1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...
- 关于调用接口 Connection reset 问题(使用代理调接口)
之前调用过别的公司的接口上传数据,但是遇到个问题就是Connection reset,查阅了网上的各种资料,说什么的都有,主要意思就是说发布接口和调用接口的某些配置不一样,但是这个怎么说呢,单方面没办 ...
- 关于webpack 开启代理proxy后,接口看不到代理地址的问题。
今天在项目中发现, 明明在proxy里代理了 接口地址确不是10.10.11.106/front/xxxxxx.这是为啥呢?changeOrigin的修改也是一样,在网络请求中发现host还是没改.这 ...
- java Proxy(代理机制)
我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...
- C++设计模式-Proxy代理模式
Proxy代理模式 作用:为其他对象提供一种代理以控制对这个对象的访问. 代理的种类: 如果按照使用目的来划分,代理有以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代 ...
- 自己写一个java.lang.reflect.Proxy代理的实现
前言 Java设计模式9:代理模式一文中,讲到了动态代理,动态代理里面用到了一个类就是java.lang.reflect.Proxy,这个类是根据代理内容为传入的接口生成代理用的.本文就自己写一个Pr ...
- Spring AOP在函数接口调用性能分析及其日志处理方面的应用
面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...
- Proxy 代理模式
简介 代理模式是用一个简单的对象来代替一个复杂的或者创建耗时的对象. java.lang.reflect.Proxy RMI 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对 ...
- 第四章:使用Proxy代理让客户端服务端分工合作。
<基于1.8 Forge的Minecraft mod制作经验分享> 别被那个Proxy代理吓到,很简单的. 我们先讨论为什么要用Proxy代理: 像打开新的UI这种操作,比如打开一个背包, ...
随机推荐
- 万字长文 | 泰康人寿基于 Apache Hudi 构建湖仓一体平台的应用实践
文章贡献者 Authors 技术指导: 泰康人寿 数据架构资深专家工程师 王可 文章作者: 泰康人寿 数据研发工程师 田昕峣 摘要 Abstract 本文详细介绍了泰康人寿基于 Apache Hudi ...
- http 500 错误
214 [Thu Sep 09 16:03:54.919334 2021] [:error] [pid 32045] [client 124.238.184.230:23796] script '/v ...
- 常见的企业Wiki
企业Wiki(Enterprise Wiki)指适用于企业或组织内部使用的Wiki.与非企业Wiki(如著名的MediaWiki)最根本的不同点在于,企业Wiki是为企业量身定做的Wiki.通过鼓励. ...
- Composite 组合模式简介与 C# 示例【结构型3】【设计模式来了_8】
〇.简介 1.什么是组合设计模式? 一句话解释: 针对树形结构的任意节点,都实现了同一接口,他们具有相同的操作,可以通过某一操作来遍历全部节点. 组合模式通过使用树形结构来组合对象,用来表示部分以 ...
- 重温dp——最长上升公共子序列
一道经典的dp了 题目描述 给出 1,2,-,n 的两个排列 P1 和 P2 ,求它们的最长公共子序列. 输入格式 第一行是一个数 n. 接下来两行,每行为 n 个数,为自然数 1,2,-,n 的一 ...
- salesforce零基础学习(一百三十三)ListView的button思考
本篇参考: salesforce零基础学习(九十五)lightning out salesforce零基础学习(一百一十)list button实现的一些有趣事情 https://help.sales ...
- 当个 PM 式程序员「GitHub 热点速览」
本周 GitHub 热点依旧是 GPT 类项目,当中的佼佼者自然是本文收录的 gpt-pilot,一周获得了 7k+ star.此外,像是 LangChain.Autogen 之类的 LLM 工具链项 ...
- Maximum Diameter 题解
Maximum Diameter 题目大意 定义长度为 \(n\) 的序列 \(a\) 的权值为: 所有的 \(n\) 个点的第 \(i\) 个点的度数为 \(a_i\) 的树的直径最大值,如果不存在 ...
- Ansible与Ansible部署
Ansible与Ansible部署 Ansible简介: Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩.它融合了众多老牌运维工具的优点,Pubbet ...
- Web SSH 的原理与在 ASP.NET Core SignalR 中的实现
前言 有个项目,需要在前端有个管理终端可以 SSH 到主控机的终端,如果不考虑用户使用 vim 等需要在控制台内现实界面的软件的话,其实使用 Process 类型去启动相应程序就够了.而这次的需求则需 ...