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这种操作,比如打开一个背包, ...
随机推荐
- python实现简单的爬虫功能
前言Python是一种广泛应用于爬虫的高级编程语言,它提供了许多强大的库和框架,可以轻松地创建自己的爬虫程序.在本文中,我们将介绍如何使用Python实现简单的爬虫功能,并提供相关的代码实例. 如何实 ...
- Springboot支持XML格式报文的传输
导入依赖-jackson-dataformat-xml <!--整合web模块--> <dependency> <groupId>org.springframewo ...
- OSPF常用配置和常用的查看命令
转载请注明出处: 1.启动OSPF进程,进入OSPF视图. [Huawei] ospf [ process-id | Router ID Router ID ] 路由器支持OSPF多进程,进程号是本地 ...
- LVGL双向链表学习笔记
LVGL双向链表学习笔记 1.LVGL链表数据类型分析 对于LVGL双向链表的使用,我们需要关注lv_ll.h和lv_ll.c两个文件,其中lv_ll.h里面包含了链表结构类型定义,以及相关API的声 ...
- Go 复合类型之字典类型介绍
Go 复合类型之字典类型介绍 目录 Go 复合类型之字典类型介绍 一.map类型介绍 1.1 什么是 map 类型? 1.2 map 类型特性 二.map 变量的声明和初始化 2.1 方法一:使用 m ...
- struct 结构体【GO 基础】
〇.前言 虽然 Go 语言中没有"类"的概念,也不支持"类"的继承等面向对象的概念,但是可以通过结构体的内嵌,再配合接口,来实现面向对象,甚至具有更高的扩展性和 ...
- python~windows自动化工具 uiautomation库
微软提供了关于自动化操作PC端桌面应用程序的工具,官方描述为: Microsoft UI Automation is an accessibility framework that enables W ...
- React项目中webpack的配置过程
初始化一个web项目 使用npm init -y 初始化一个项目 在项目目录下创建src, dist文件夹,创建webpack.config.js配置文件 然后在src文件夹下创建index.js, ...
- Hyper-V 下的 Debian 双网卡配置
Debian 双网卡配置 因为 Hyper-v 不能在 Hyper-v Manger 里设置网卡的静态 IP, 而每次开机自启之后又要连接 Debian 虚拟机,所以使用了双网卡. 双网卡分为内网网卡 ...
- Redis平台-整合PHP
1.Redis的相关介绍: 定义: redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合 ...