当前位置: 首页 > 编程日记 > 正文

利用反射实现类的动态加载

为什么80%的码农都做不了架构师?>>>   hot3.png


//首先定义一个接口来隔离类:
public interface Operator
{
//    public java.util.List act(java.util.List params);public java.util.List act(String content,String content2,java.util.List params);
}


根据设计模式的原理,我们可以为不同的功能编写不同的类,每个类都继承Operator接口,客户端只需要针对Operator接口编程就可以避免很多麻烦。比如这个类:

import java.util.*;
public class Success implements Operator
{public static void main(String[] args) {List list = new ArrayList();list.add("Success3");Operator op = new Success();System.out.println("act===" + op.act("Success1", "Success2", list));}
//       public java.util.List act(java.util.List params)public java.util.List act(String content, String content2,java.util.List params) {List result = new ArrayList();result.add(content);result.add(content2);result.add(params);return result;}
}

同样,也可以写另一个类:

import java.util.*;
public class Load implements Operator
{public static void main(String[] args) {List list = new ArrayList();list.add("Load3");Operator op = new Load();System.out.println("act===" + op.act("Load1", "Load2", list));}
//       public java.util.List act(java.util.List params)public java.util.List act(String content, String content2,java.util.List params){List result = new ArrayList();result.add(content);result.add(content2);result.add(params);return result;}
}

我们还可以写其他很多类,但是有个问题,接口是无法实例化的,我们必须手动控制具体实例化哪个类,这很不爽,如果能够向应用程序传递一个参数,让自己去选择实例化一个类,执行它的act方法,那我们的工作就轻松多了。
 
很幸运,我使用的是Java,只有Java才提供这样的反射机制,或者说内省机制,可以实现我们的无理要求。编写一个配置文件emp.properties: 
#成功响应

1000=Success

#向客户发送普通文本消息

2000=Load

#客户向服务器发送普通文本消息

3000=Store

文件中的键名是客户将发给我的消息头,客户发送1000给我,那么我就执行Success类的act方法,类似的如果发送2000给我,那就执行Load类的act方法,这样一来系统就完全符合开闭原则了,如果要添加新的功能,完全不需要修改已有代码,只需要在配置文件中添加对应规则,然后编写新的类,实现act方法就ok,即使我弃这个项目而去,它将来也可以很好的扩展。这样的系统具备了非常良好的扩展性和可插入性。 
下面这个例子体现了动态加载的功能,程序在执行过程中才知道应该实例化哪个类:

import java.lang.reflect.*;
import java.util.Properties;
import java.io.FileInputStream;
import java.util.List;
//这个程序是针对Operator编程的,所以无需做任何修改,直接提供Load和Store类,就可以支持2000、3000做参数的调用
//有了这样的内省机制,可以把接口的作用发挥到极至,设计模式也更能体现出威力,而不仅仅供我们饭后闲聊。
public class TestReflect
{//加载配置文件,查询消息头对应的类名private String loadProtocal(String header){String result=null;try{Properties prop=new Properties();
//           FileInputStream fis=new FileInputStream("emp.properties");
//           id = prop.getProperty(idString);
//           prop.load(fis);
//           fis.close();prop.load(getTCL().getResourceAsStream("emp.properties"));result=prop.getProperty(header);}catch(Exception e){System.out.println(e);}return result;}private static ClassLoader getTCL() throws IllegalAccessException,InvocationTargetException {Method method = null;try {method = Thread.class.getMethod("getContextClassLoader", null);} catch (NoSuchMethodException e) {return null;}return (ClassLoader)method.invoke(Thread.currentThread(), null);}//针对消息作出响应,利用反射导入对应的类public String response(String header,String content,String content2,List list){String result=null;String s=null;try{/** 导入属性文件emp.properties,查询header所对应的类的名字* 通过反射机制动态加载匹配的类,所有的类都被Operator接口隔离* 可以通过修改属性文件、添加新的类(继承MsgOperator接口)来扩展协议*/s="org.bromon.reflect."+this.loadProtocal(header).trim();//加载类System.out.println("s==="+s);//打印 s===org.bromon.reflect.SuccessClass c=Class.forName(s);
//java.lang.reflect.Methods 是用来描述某个类中单个方法的一个类
//           Method m[] = c.getDeclaredMethods();//
//           for (int i = 0; i < m.length; i++)//
//               System.out.println(m[i].toString());
//  打印   public java.util.List org.bromon.reflect.Success.act(java.util.List)//创建类的事例Operator mo=(Operator)c.newInstance();System.out.println("mo==="+mo);//构造参数列表Class params[]=new Class[3];
//           params[0]=Class.forName("java.util.List");params[0]=Class.forName("java.lang.String");params[1]=Class.forName("java.lang.String");params[2]=Class.forName("java.util.List");System.out.println("params[0]==="+params[0]);
//           //查询act方法Method m=c.getMethod("act",params);System.out.println("method=="+m.toString());Object[] args=new Object[3];args[0]=content;args[1]=content2;args[2]=list;
//           //调用方法并且获得返回Object returnObject=m.invoke(mo,args);//这个地方出问题了,抛异常~~~~
//           System.out.println("returnObject==="+returnObject);List result2 = (List)returnObject;result = (String)result2.get(0);System.out.println("result2=="+result2);
//}catch(Exception e){System.out.println("Handler-response:"+e);//Handler-response:java.lang.IllegalArgumentException: argument type mismatch//IllegalArgumentException - 如果该方法是实例方法,且指定对象参数不是声明基础方法的类或接口(或其中的子类或实现程序)的实例;//如果实参和形参的数量不相同;如果基本参数的解包转换失败;或者如果在解包后,无法通过方法调用转换将参数值转换为相应的形参类型。}return result;}public static void main(String args[]){TestReflect tr=new TestReflect();List list = new java.util.ArrayList();list.add("测试List");tr.response("2000","Load1","Load2",list);//1000是Success,2000是Loadtr.response("1000","Success1","Success2",list);//1000是Success,2000是Load}
}

测试一下,run一下TestReflect类,打印内容有,great!!
result2==[Load1, Load2, [测试List]]
result2==[Success1, Success2, [测试List]]

这个程序是针对Operator编程的,所以无需做任何修改,直接提供Load和Store类,就可以支持2000、3000做参数的调用。
        有了这样的内省机制,可以把接口的作用发挥到极至,设计模式也更能体现出威力,而不仅仅供我们饭后闲聊.

转载于:https://my.oschina.net/exit/blog/153241

相关文章:

spring+ (activeMQ) 实现queue与topic

2019独角兽企业重金招聘Python工程师标准>>> 2017-06-17 1、activeMQ下载与安装 前往Apache官网下载ActiveMQ&#xff0c;下载地址http://activemq.apache.org/download.html&#xff08;此处我下载了apache-activemq-5.9.0 版本的tar包&#xff09;解压&#xff1a…

C#文本文件操作

如何向现有文件中添加文本using System;using System.IO;class Test {public static void Main() {// Create an instance of StreamWriter to write text to a file.// The using statement also closes the StreamWriter.using (StreamWriter sw new StreamWriter("Tes…

RISC-V 正在成为芯片世界中的 Linux

【编者按】芯片推动了人类社会数字化、信息化、智能化的发展。从某种程度上来说&#xff0c;芯片技术的发展也影响着行业未来的走向。你觉得未来的芯片世界将会如何&#xff1f;编译 | 虎说八道 责编 | 张文头图 | CSDN 下载自视觉中国出品 | CSDN&#xff08;ID&#xff1a;C…

linux系统小记

1.当某分区空间剩余很大时&#xff0c;可用dd命令写入0&#xff0c;做成很大的文件后格式化&#xff0c;可当作分区使用&#xff08;-o loop挂载&#xff09;#dd if/dev/zero of/wq bs1M count512#mkfs -t ext3 /wq#mkswap /wq#swapon /wq#mount -o loop /wq /data#mou…

网络编程 -- RPC实现原理 -- RPC -- 迭代版本V3 -- 远程方法调用 整合 Spring

网络编程 -- RPC实现原理 -- 目录 啦啦啦 V3——RPC -- 远程方法调用 及 null的传输 Spring 服务提供商&#xff1a; 1. 配置 rpc03_server.xml 注入 服务提供商 rpcServiceProvider并指定初始化方法 及 服务实例 IUserService 2. 读取 服务消费者 请求的 MethodStaics &…

Rootkit之SSDT hook(通过CR0)

SSDT即System Service Dispath Table&#xff0c;它是一个表&#xff0c;这个表中有内核调用的函数地址。KeServiceDescriptorTable&#xff1a;是由内核&#xff08;Ntoskrnl.exe&#xff09;导出的一个表&#xff0c;这个表是访问SSDT的关键&#xff0c;具体结构是typedef st…

禁止validateRequest的办法

A potentially dangerous Request.Form value was detected from the client (txtTest"<b>"). 由于在.net中&#xff0c;Request时出现有HTML或Javascript等字符串时&#xff0c;系统会认为是危险性值。立马报错。 解决方案一&#xff1a; 在.a…

多画面、实时投票,这场上了一晚热搜的超级晚,背后的技术出圈了

"让观众当导演&#xff0c;自己决定演出顺序&#xff1f;" "不仅直播前台演出&#xff0c;还可以看到候场区明星吃火锅&#xff1f;" 你没听错&#xff0c;在各种直播、晚会频出的岁末年初&#xff0c;最近有一台超级晚出圈了。 1月15日&#xff0c;2021爱…

linux下挂载硬盘

2019独角兽企业重金招聘Python工程师标准>>> 切换到root用户 su - root 查看硬盘信息 fdisk -l Disk /dev/sda: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units cylinders of 16065 * 512 8225280 bytes Sector size (logical/ph…

通过创建 HttpCookie 对象的实例编写 Cookie

通过创建 HttpCookie 对象的实例编写 Cookie HttpCookie myCookie new HttpCookie("UserSettings");myCookie["Font"] "Arial";myCookie["Color"] "Blue";myCookie.Expires DateTime.Now.AddDays(1d);Response.Cookies…

亚马逊云服务(AWS)云原生自研处理器首次落地中国区域!

2021年1月28日&#xff0c;亚马逊云服务&#xff08;AWS&#xff09;正式宣布&#xff0c;由 AWS Graviton2 处理器提供支持的 Amazon Elastic Compute Cloud &#xff08;Amazon EC2&#xff09; M6g、C6g 和 R6g 实例已在由光环新网运营的 AWS 中国&#xff08;北京&#xff…

一个古老的问题HashMap与Hashtable区别

HashTable的应用非常广泛&#xff0c;HashMap是新框架中用来代替HashTable的类&#xff0c;也就是说建议使用HashMap&#xff0c;不要使用HashTable。可能你觉得HashTable很好用&#xff0c;为什么不用呢&#xff1f;这里简单分析他们的区别。 1.HashTable的方法是同步的&#…

如何修改可运行Jar包,如何反编译Jar包

将可运行Jar包&#xff0c;反编译成项目&#xff0c;修改代码&#xff0c;再次编译&#xff0c;打包。 需要工具&#xff1a;jd-gui、myeclipse 具体步骤&#xff1a; 1、使用jd-gui打开原始的Jar包&#xff0c;选择File-->Save All Sources&#xff0c;会生成一个zip压缩包…

告别手敲 SQL ?GPT-3 自动帮你写

作者 | Brian Kane SeekWell 编译 | 伍杏玲 出品 | AI科技大本营&#xff08;ID&#xff1a;rgznai100&#xff09; 【导语】手写业务 SQL 很繁琐&#xff1f;GPT-3来帮你&#xff01;本文作者通过手动输入简单的英文描述秒 Get 到 SQL 了。听说 AI 又来抢开发者饭碗&#xff0…

Java IO 体系结构

参考文章地址: http://blog.csdn.net/oracle_microsoft/article/details/2634231 Java IO体系结构看似庞大复杂,其实有规律可循,要弄清楚其结构,需要明白两点: 1. 其对称性质:InputStream 与 OutputStream, Reader 与 Writer,他们分别是一套字节输入-输出,字符输入-输出体系 2.…

ACCESS数据库防止下载

1. 修改数据库名。这是常用方法&#xff0c;将数据库名该成怪异名字或长名字&#xff0c;以防别人猜测。一旦被人猜到&#xff0c;别人还是能下载数据库文件&#xff0c;但几率不大。如将数据库database.mdb改成dslfjds$^&ijjkgf.mdb等 2. 修改数据库后缀。一般改成databa…

CentOS 7 SSH 免密登录的方法

先决条件 3 台 CentOS 7 HOSTNAMEIPROLEserver110.8.26.197Masterserver210.8.26.196Slave1server310.8.26.195Slave21. 用 root 用户登录。每台服务器都生成公钥&#xff0c;再合并到 authorized_keys。 2. CentOS 默认没有启动 ssh 无密登录&#xff0c;去掉 /etc/ssh/sshd_c…

webconfig加密

退到根目录 cd/跳到某盘 c: ..跳到某目录 cd Documents and Settings/All Users上一层 cd .. cd WINDOWS/Microsoft.NET/Framework/v2.0.50727 回车 aspnet_regiis -pef connectionStrings D:/NET aspnet_regiis -pe connectionStrings -app /NET 虚拟目录aspnet_regiis -pd…

WIN7 任务栏放右侧 有个BUG

不能变窄啊&#xff0c;微软又在设计上。转载于:https://www.cnblogs.com/whitetiger/p/3269827.html

全领域通吃,12个经典Python数据可视化库盘点

责编 | 寇雪芹头图 | 下载于视觉中国来源 | 博文视点BroadviewPython有很多数据可视化库&#xff0c;这些数据可视化库主要分为探索式可视化库和交互式可视化库。前者透过简单直接的视觉图形&#xff0c;更方便用户看懂原数据&#xff0c;后者主要用于与业务结合过程中展现总体…

add nodes to the swarm

一旦你们创建了一个带有管理节点的swarm集群&#xff0c;你就可以开始添加 worker节点$ docker-machine ssh worker1 $ docker swarm join \--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \192.168.99.100:2377 This node …

三种方法,用Python轻松提取PDF中的全部图片

作者 | 陈熹、刘早起来源 | 早起Python头图 | 下载于视觉中国有时我们需要将一份或者多份PDF文件中的图片提取出来&#xff0c;如果采取在线的网站实现的话又担心图片泄漏&#xff0c;手动操作又觉得麻烦&#xff0c;其实用Python也可以轻松搞定&#xff01;今天就跟大家系统分…

ASP.NET中如何防范SQL注入式攻击

1将sql中使用的一些特殊符号&#xff0c;如 -- /* ; %等用Replace()过滤&#xff1b;2限制文本框输入字符的长度&#xff1b;3检查用户输入的合法性&#xff1b;客户端与服务器端都要执行&#xff0c;可以使用正则。4使用带参数的SQL语句形式。 ASP.NET中如何防范SQL注入式攻击…

iOS下的类似Android的toast提示

一般人会说&#xff0c;就是用那个MBProgressHUD不就行了吗&#xff1f; 的确是&#xff0c;MBProgressHUD能为我们做了好多loading指示器&#xff0c;但是toast不一样&#xff0c;它是在屏幕某个地方出现一行小提示&#xff0c;例如网络状态&#xff0c;出现的时候不会妨碍用户…

配置Activiti Explorer使用MYSQL

http://blog.csdn.net/lxxxzzl/article/details/39583977

初学者SQL语句介绍

初学者SQL语句介绍 1.用 Select 子句检索记录 Select 子句是每一个检索数据的查询核心。它告诉数据库引擎返回什么字段。 Select 子句的常见形式是&#xff1a; Select * 该子句的意思是“返回在所指定的记录源中能找到的所有字段”。这种命令形式很方便&#xff…

转型AI成功几率有几分?太真实了......

技术转型&#xff0c;这两年一直是程序员圈子里的热门话题。对于大部分基层程序员来说&#xff0c;基础岗位上薪资的涨幅很难跟上年龄的增长。而近些年&#xff0c;AI技术发展势头迅猛&#xff0c;优秀人才短缺。在这种情况下&#xff0c;无疑是谁先转型成功&#xff0c;谁就占…

如何使用聚簇索引

2019独角兽企业重金招聘Python工程师标准>>> 聚簇索引是一种对磁盘上实际数据重新组织以按指定的一个或多个列的值排序。由于聚簇索引的索引页面指针指向数据页面&#xff0c;所以使用聚簇索引查找数据几乎 总是比使用非聚簇索引快。每张表只能建一个聚簇索引&#…

C语言实现汉诺塔问题

代码如下&#xff1a; #include <stdio.h> #include <stdlib.h> void move(int n,char x,char y,char z) {if (n1) {printf("%c--->%c\n",x,z);}else {move(n-1,x,z,y);printf("%c--->%c\n",x,z);move(n-1,y,x,z);} } int main() {int n…

将Session值储存于SQL Server中

一般情况下&#xff0c;我们喜欢使用Session储存我们的变量。Asp.Net提供了下面一些方法储存Session的值&#xff1a; InProc State Server SQL Server “InProc”表示我们使用传统ASP一样的方法储存Session的值&#xff0c;而且“State Server”则表示使用另外一台主机来…