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代理实现接口调用处理的更多相关文章

  1. requests使用“proxy”代理访问接口

    在requests中使用proxy代理访问 使用前先更新requests版本为支持socks的版本.   先pip安装对应库:  >> pip install -U requests[so ...

  2. SpringBoot27 JDK动态代理详解、获取指定的类类型、动态注册Bean、接口调用框架

    1 JDK动态代理详解 静态代理.JDK动态代理.Cglib动态代理的简单实现方式和区别请参见我的另外一篇博文. 1.1 JDK代理的基本步骤 >通过实现InvocationHandler接口来 ...

  3. 关于调用接口 Connection reset 问题(使用代理调接口)

    之前调用过别的公司的接口上传数据,但是遇到个问题就是Connection reset,查阅了网上的各种资料,说什么的都有,主要意思就是说发布接口和调用接口的某些配置不一样,但是这个怎么说呢,单方面没办 ...

  4. 关于webpack 开启代理proxy后,接口看不到代理地址的问题。

    今天在项目中发现, 明明在proxy里代理了 接口地址确不是10.10.11.106/front/xxxxxx.这是为啥呢?changeOrigin的修改也是一样,在网络请求中发现host还是没改.这 ...

  5. java Proxy(代理机制)

    我们知道Spring主要有两大思想,一个是IoC,另一个就是AOP,对于IoC,依赖注入就不用多说了,而对于Spring的核心AOP来说,我们不但要知道怎么通过AOP来满足的我们的功能,我们更需要学习 ...

  6. C++设计模式-Proxy代理模式

    Proxy代理模式 作用:为其他对象提供一种代理以控制对这个对象的访问. 代理的种类: 如果按照使用目的来划分,代理有以下几种: 远程(Remote)代理:为一个位于不同的地址空间的对象提供一个局域代 ...

  7. 自己写一个java.lang.reflect.Proxy代理的实现

    前言 Java设计模式9:代理模式一文中,讲到了动态代理,动态代理里面用到了一个类就是java.lang.reflect.Proxy,这个类是根据代理内容为传入的接口生成代理用的.本文就自己写一个Pr ...

  8. Spring AOP在函数接口调用性能分析及其日志处理方面的应用

    面向切面编程可以实现在不修改原来代码的情况下,增加我们所需的业务处理逻辑,比如:添加日志.本文AOP实例是基于Aspect Around注解实现的,我们需要在调用API函数的时候,统计函数调用的具体信 ...

  9. Proxy 代理模式

    简介 代理模式是用一个简单的对象来代替一个复杂的或者创建耗时的对象. java.lang.reflect.Proxy RMI 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对 ...

  10. 第四章:使用Proxy代理让客户端服务端分工合作。

    <基于1.8 Forge的Minecraft mod制作经验分享> 别被那个Proxy代理吓到,很简单的. 我们先讨论为什么要用Proxy代理: 像打开新的UI这种操作,比如打开一个背包, ...

随机推荐

  1. C#开源且免费的Windows桌面快速预览神器 - QuickLook

    前言 今天给大家推荐一款由C#开源且免费的Windows桌面快速预览神器:QuickLook. 工具介绍 QuickLook是一款在Windows操作系统上的实用工具,它提供了一种快速预览文件内容的方 ...

  2. 甲骨文宣布: 也做 PostgreSQL!

    PostgreSQL 在开源数据库世界中一直是一个标志性的存在.经过35年的严格开发,它以其可靠性.强大的功能和性能而自豪.DB-engines 的突出显示,其市场份额的增长证明了其适应性强的数据模型 ...

  3. 08-03_阅读flask上下文前夕补充、flask请求上下文、数据库连接池

    文章目录 阅读flask上下文前夕补充 01 偏函数 02 __add__的使用 03 chain函数 2 flask请求上下文 1 首先分析请求上下文对象(ctx)创立 2 把请求对象(ctx)添加 ...

  4. Python面试题——面向对象题

    1.简述面向对象的三大特性. 封装: 封装指的是把一堆数据属性与方法数据放在一个容器中,这个容器就是对象.让对象可以通过 "." 来调用对象中的数据属性与方法属性. 继承: 继承指 ...

  5. 算法学习笔记(3.1): ST算法

    ST表 在RMQ(区间最值)问题中,著名的ST算法就是倍增的产物.ST算法可以在 \(O(n \log n)\) 的时间复杂度能预处理后,以 \(O(1)\) 的复杂度在线回答区间 [l, r] 内的 ...

  6. CDQ分治和三维偏序

    专题:CDQ 分治 本页面将完整介绍 CDQ 分治. 简介 CDQ 分治是一种思想而不是具体的算法,与动态规划类似.目前这个思想的拓展十分广泛,依原理与写法的不同,大致分为三类: 解决和点对有关的问题 ...

  7. 【羚珑AI智绘营】分分钟带你拿捏SD中的色彩控制

    导言 颜色控制一直是AIGC的难点,prompt会污染.img2img太随机- 今天带来利用controlnet,实现对画面颜色的有效控制.都说AIGC是抽卡,但对把它作为工具而非玩具的设计师,必须掌 ...

  8. 2D物理引擎 Box2D for javascript Games 第六章 关节和马达

    2D物理引擎 Box2D for javascript Games 第六章 关节和马达 关节和马达 到现在你所见到的所有类型的刚体有着一些共同点:它们都是自由的并且在除碰撞的请款之外,彼此没有依赖. ...

  9. TechEmpower 22轮Web框架 性能评测:.NET 8 战绩斐然

    自从2022年7月第21轮公布的测试以后,一年后 的2023年10月17日 发布了 TechEmpower 22轮测试报告 刚刚发布:Round 22 results - TechEmpower Fr ...

  10. Verilog语法基础

    FPGA语法 逻辑值: 0:逻辑低电平,条件为假. 1:逻辑高电平,条件为真. z:高阻态,无驱动 x:未知逻辑电平,这既不是0也不是1,只是一个不稳定的状态. 关键字: module:表示模块的开始 ...