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. mpi转以太网Plus模块连接300PLC实现MPI转modbus通信

    西门子200/300PLC转以太网同时实现PPI/MPI/DP转modbus通信 产品简介 MPI-ETH-XD1.0plus是在MPI-ETH-XD1.0的基础上,以太网口增加了支持与西门子带网口P ...

  2. elementui vue表单提交向别的组件传参失效 路由传参格式

    目录 表单提交向别的组件传参失效 路由传参格式 表单提交向别的组件传参失效 methods: { submitForm(formName) { this.$refs[formName].validat ...

  3. CDQ分治和三维偏序

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

  4. Godot - 创建翻译文件(常量表)

    版本 Godot 3.1.2 背景 Godot的UI系统封装的很难受, 一些东西很难改动, 比如这个AcceptDialog的"确定""取消"按钮, 特别是在编 ...

  5. 2022-10-22 CSP赛前隔离时的模拟赛 2:3

    T1 简单红题,不懈于写. 锐评:镜子反射出来的竟然没有镜像一下. T2 坑人东西调了 2h. 类似于 round1 的 T4. 线性 \(\Theta(n)\) 过. T3 T4 其实简单,负边权要 ...

  6. DP优化方法杂记

    一些奇妙trick 观察决策集合 此类问题与单调队列优化dp有部分相似,都是利用决策集合的特殊性质对dp进行优化. CF229D Towers 题意:给出一个序列,每次可以花费一体力合并相邻两个数,问 ...

  7. 使用Python批量发送个性化邮件

    前言 在现代工作环境中,我们经常需要向多个收件人发送个性化的邮件.通过使用Python编程语言,我们可以自动化这个过程,从Excel文件中读取收件人和相关数据,并发送定制的邮件. 首先,导入所需的库: ...

  8. 电路中的N.M.缩写含义

    国外的一些电路中会发现在一些器件旁会有 N.M. 的标注. N.M. = Not Mount

  9. decltype关键词

    简述 decltype 是 C++11 新增的一个关键字,它和 auto 的功能一样,都用来在编译时期进行自动类型推导. decltype 是"declare type"的缩写,译 ...

  10. Educational Codeforces Round 127 (Rated for Div. 2) E. Preorder

    设\(f[v]\)是以结点\(v\)为根的方案数,设左子树的根为\(x\),右子树的根为\(y\),那么如果左右子树完全相同,那么我们交换左右子树对方案没有任何影响,都是: \[f[v] = f[x] ...