java分发器 及(注解 + 反射机制)—————— 开开开山怪

2024-02-07 07:48

本文主要是介绍java分发器 及(注解 + 反射机制)—————— 开开开山怪,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

java分发器 及 (注解 + 反射机制)

引 入:

在C/S框架应用中,当应用层通过点击界面的按钮进行资源的请求的时候,请求的背后代码的实现实际上会自动构成一系列的requst信息请求,由C/S框架内部的communcation层进行消息的发送,服务器通过解析requst请求获取到action(希望服务器端做出的响应)来调用已经配置好的对应的action的方法来进行请求的响应工作,当然这些方法的调用是通过反射机制类调用的。

对于服务器来说只用做一件事请就是,解析requst获取到action,然后自动调用action对应的方法,这就是我所理解的分发。

那上边我可以总结出两个关键字:1.配置2.反射调用(分发过程)

配 置:

先说配置问题,这应该是针对引用C/S框架的编程者来说的,因为采用C/S框架来进行开发,提供给应用者的一些请求功能和对应响应这些请求的方法是相辅相成的。现在我举个栗子,如果编程者提供给用户登录的功能,那对应就会有login方法作为配置文件的方法,当然文件的配置也很有讲究。

下面我给出配置方法。
在这里插入图片描述
这是我所配置的类,在这个类中包含了三个注解,我来一一说明。

1.classAction注解:
这个注解是在类上进行的,主要是为了方便我们识别这个类是我们需要扫描的类,因为这个类所包含的方法就是专门处理请求响应的。我们扫描到这个类,才对里边的方法进行收集,到最终供服务器完成响应的时候调用这些方法来实现。

2.actionMethod注解
这个注解上有对应的值,事实上拥有这些注解的方法才值得我们被扫描,并且注解上的值对应着我们的方法名称,每扫描一个这个注解的方法,我们便用一个classDefination来封装(classDefination这个类下面马上说到),并且利用classFactory类形成一个map<String,classDefination>, map中的键为String,事实上就是方法注解上对应的值(也可以说这个值就是这个方法的标志),map中的值就是一个个封装方法的classDefination。

那为什么要这样封装并形成一个map呢???

原因是这样,我们进行这样的配置并采用map来进行收集,为了服务器在响应请求的时候可以直接从requst请求中解析出action(action事实上和方法上注解的值是相对应的,因为我说过了,编程者写一个action,那它自然知道对应哪个方法,方法的注解的值当然和action是一一对应),根据action在map中找到对应的键,并且得到对应action方法的classDefination对象。因为classDefination类中的成员包括method,当然可以采用method.invoke()反射机制的方法来调用该方法实现响应操作。

3.actionPara注解
这个注解有意思了,因为method.invoke()事实上是需要参数的,一个参数就是该方法所在的类的对象,还有一个就是该方法的真实参数的一个数组。
这个注解是在参数上的,那必然是辅助method.invoke()这个方法的,下面我会详细说。

先给出上面我说的classDefination类和classFactory吧,不然你们还不知道咋回事儿呢。

classDefination类

public class classDefination {private Class<?> className;private Method method;private Object object;public Class<?> getClassName() {return className;}public void setClassName(Class<?> className) {this.className = className;}public Method getMethod() {return method;}public void setMethod(Method method) {this.method = method;}public Object getObject() {return object;}public void setObject(Object object) {this.object = object;}
}
classFactory类
public class classFactory {private static final Map<String, classDefination> map = new HashMap<String, classDefination>();public classFactory() {}public static void parserAnno(String packetName) { new PackageScanner() {   @Overridepublic void dealClass(Class<?> klass) {//通过包扫描到这种的类,循环分析每一个类if (klass.isAnnotationPresent(classAction.class)) {//如果类有该注解try {Object object =  klass.newInstance();Method[] method = klass.getDeclaredMethods();      for (Method one : method) {if (one.isAnnotationPresent(actionMethod.class)) {//总结当前的房的的一套classDefinationclassDefination cdf = new classDefination();actionMethod am = one.getAnnotation(actionMethod.class);cdf.setObject(object);cdf.setMethod(one);cdf.setClassName(klass);map.put(am.methodName(), cdf);         }}     } catch (Exception e) {   e.printStackTrace();}     }   }}.scanPackage(packetName); }public static Map<String, classDefination> getMap() {return map;}public static classDefination getByKey(String methodName) {System.out.println(map);return map.get(methodName);}}

分发开始了:

前面我说过了,既然编程者提供了功能,那就会有自己针对功能请求相应的响应功能的方法。我采用一个 登陆功能(相当于用户端的某一个请求)举个栗子,并且以下的内容采用登陆进行说明。

用户请求登陆,在登陆请求背后的代码事实上就是由C/S框架的cilent层requst()方法进行请求的发送,然后通过communcation层将请求传送给服务器。

图一

在这里插入图片描述

图二在这里插入图片描述

requst()实际上发送的内容有三个部分:
1.REQUST 这是C/S内部用来识别并且处理requst请求的标志,
2.action 这是用户真正的请求,例如此时的action = login
3.content 这是用来请求响应所需要的条件,此时的content 是由 userName:XXXX passWord:XXXX 组成的一个字符串,此时的 userName:XXXX passWord:XXXX是由makePar类来进行包装的,这里的 userName 和 passWord 其实对应到上面我们配置方法的参数名称。

这三部分用Message类来进行包装,然后转化为字符串交给服务器,服务器根据字符串反解析成Message类型,并从中获取到对应的command = REQUST,在这个REQUST的switch case下就真正的开始进行分发了。

图三

在这里插入图片描述

此时dealAction类出现了,这个类就是我们专门处理响应配置方法的类,因为在Message中我们还能得到 actioncontent ,这是这两个值就作为dealAction 方法的参数。

dealAction这个类中干的事情就很明确了,就是通过action在我们之前准备好的map中得到对应的classDefinition,从classDefinition中得到method成员和object成员,此时就只需要通过method.invoke(object, object[ ]), 来进行反射调用我们配置好的方法,invoke的第二个参数就是方法所需要的真正参数的数组,这就是为什么之前的 actionPara注解 存在的原因了。因为我们dealAction传进来的参数content是一个字符串,我们只有将这个字符串转化成真正的方法参数(具体转化过程及为什么要存在actionPara注解请阅读 Google中Gson的巧妙使用)就可以可以反射机制调用方法进行响应的操作。

public interface IdealAction {String deal(String action, String text) throws Exception ;}
public class dealAction implements IdealAction{private static final Gson gson = new GsonBuilder().create();public dealAction() {}private Object[] getParaValues(Method method, String para) throws Exception {Parameter[] paras = method.getParameters();//根据参数个数构造真实参数的数组if(paras.length <= 0) {return new Object[] {};}Object[] realParas = new Object[paras.length];makePar mp = new makePar(para);//会产生一个map,将para分解成键值对的形式for (int i = 0; i < paras.length; i++) {Parameter p = paras[i];if (!p.isAnnotationPresent(actionPara.class)) {throw new Exception("第" + (i + 1 ) + "个参数没有注解");}actionPara at = p.getAnnotation(actionPara.class);String name = at.paraName();Type tp = p.getParameterizedType();realParas[i] = mp.getParaValue(name, tp);}return realParas;}@Overridepublic String deal(String action, String text) throws Exception {//在这之前应该得到相应的classFactory的信息classDefination cdf = classFactory.getByKey(action);if (cdf == null) {throw new Exception("action" + (action) + "未定义");}//通过cdf可以知道参数的名称和参数的类型,可以对应传递过来的字符串,通过名称找到对应的键值//并且通过类型将相应的键值转化成真正的值进行方法的调用Method method = cdf.getMethod(); Object result = method.invoke(cdf.getObject(), getParaValues(method, text));return gson.toJson(result);}}

这篇关于java分发器 及(注解 + 反射机制)—————— 开开开山怪的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/687018

相关文章

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

SpringCloud动态配置注解@RefreshScope与@Component的深度解析

《SpringCloud动态配置注解@RefreshScope与@Component的深度解析》在现代微服务架构中,动态配置管理是一个关键需求,本文将为大家介绍SpringCloud中相关的注解@Re... 目录引言1. @RefreshScope 的作用与原理1.1 什么是 @RefreshScope1.

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.