dubbo-源码阅读之javaspi&javasist简单使用
dubbo可扩展的点的类的对象创建 都是用类似javaspi和javasist的思想来做的。所以看后面代码 先熟悉一下java的SPI和javasist的使用
如ServicesConfig的代码
private static final Protocol protocol = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();
JAVASPI的作用
服务(接口实现类)的自动发现。我们定义好一组接口标准。而具体实现调用者根据自身需求自己实现
JavaSPI简单使用
我们模拟我们做了一个框架(jar) 框架的正常运行需要相关配置。配置加载方式由使用者来实现
1.定义接口
/** * 加载配置文件的句柄 */ public interface LoadConfigHandle { public String load(); }
2.定义实现类
public class HttpLoadConfigHandle implements LoadConfigHandle { public String load() { System.out.println("正在用http请求加载配置文件数据"); return ""; } }
public class XmlLoadConfigHandle implements LoadConfigHandle { public String load() { System.out.println("正在加载配置文件xml"); return ""; } }
在resource创建META-INF文件夹,再创建一个与接口全名称同名的文件。将实现类配置进去
com.liqiang.spi.XmlLoadConfigHandle com.liqiang.spi.HttpLoadConfigHandle
3测试
public static void main(String[] str) throws InterruptedException { ServiceLoader<LoadConfigHandle> serviceLoader = ServiceLoader.load(LoadConfigHandle.class); Iterator<LoadConfigHandle> iterator = serviceLoader.iterator(); while (iterator.hasNext()) {//next时候查缓存有没有加载过。如果没有加载才去加载 LoadConfigHandle loadConfigHandle = iterator.next();//next时候查缓存有没有加载过。如果没有加载采取加载
loadConfigHandle.load(); } }
javasist使用
假设我们在运行时要动态的创建和编译类这样一个类
package com.liqiang.ssist; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Person(String name, int age){ this.name=name; this.age=age; } public void show(String ... date){ System.out.println(this.name+"|"+this.age); } }
public static void main(String[]str) throws Exception{ //ClassPool:CtClass对象的容器 ClassPool pool = ClassPool.getDefault(); //通过ClassPool生成一个public新类Emp.java CtClass ctClass = pool.makeClass("com.liqiang.ssist.Person"); /** * 创建字段 */ //创建字段private String name; CtField nameField = new CtField(pool.getCtClass("java.lang.String"),"name",ctClass); nameField.setModifiers(Modifier.PRIVATE);//私有字段 ctClass.addField(nameField); //创建字段private int age; CtField ageField = new CtField(pool.getCtClass("java.lang.Integer"),"age",ctClass); ageField.setModifiers(Modifier.PRIVATE);//私有字段 ctClass.addField(ageField); /** * 为他们添加添加get set个访问器 */ ctClass.addMethod(CtNewMethod.getter("getName", nameField)); ctClass.addMethod(CtNewMethod.setter("setName", nameField)); ctClass.addMethod(CtNewMethod.getter("getAge", ageField)); ctClass.addMethod(CtNewMethod.setter("setAge", ageField)); /** * 添加构造函数 */ CtConstructor ctConstructor = new CtConstructor(new CtClass[]{pool.getCtClass("java.lang.String"), pool.getCtClass("java.lang.Integer")}, ctClass); //为构造函数设置函数体$1表示第一个参数 $2表示第二个参数 StringBuffer buffer = new StringBuffer(); buffer.append("{\n") .append("name=$1;\n") .append("age=$2;\n}"); ctConstructor.setBody(buffer.toString()); //把构造函数添加到新的类中 ctClass.addConstructor(ctConstructor); /** * 定义方法 */ CtMethod ctMethod = new CtMethod(CtClass.voidType,"show",new CtClass[]{},ctClass); //为自定义方法设置修饰符 ctMethod.setModifiers(Modifier.PUBLIC); //为自定义方法设置函数体 StringBuffer buffer2 = new StringBuffer(); buffer2.append("{\nSystem.out.println(this.name+\"|\"+this.age);\n") .append("}"); ctMethod.setBody(buffer2.toString()); ctClass.addMethod(ctMethod); /** * 反射生成实体 */ Class<?> clazz = ctClass.toClass(); Constructor cla = clazz.getDeclaredConstructor(String.class,Integer.class);//获取构造函数的构造器 Object obj=cla.newInstance("小明",12);//调用构造器生成对象 obj.getClass().getMethod("show", new Class[]{}).invoke(obj, new Object[]{}); }
输出
还有更多的使用方法 动态继承实现类。动态改变类方法 增加方法等。
dubbo-源码阅读之javaspi&javasist简单使用的更多相关文章
- 【Dubbo源码阅读系列】之远程服务调用(上)
今天打算来讲一讲 Dubbo 服务远程调用.笔者在开始看 Dubbo 远程服务相关源码的时候,看的有点迷糊.后来慢慢明白 Dubbo 远程服务的调用的本质就是动态代理模式的一种实现.本地消费者无须知道 ...
- 【Dubbo源码阅读系列】服务暴露之远程暴露
引言 什么叫 远程暴露 ?试着想象着这么一种场景:假设我们新增了一台服务器 A,专门用于发送短信提示给指定用户.那么问题来了,我们的 Message 服务上线之后,应该如何告知调用方服务器,服务器 A ...
- 【Dubbo源码阅读系列】服务暴露之本地暴露
在上一篇文章中我们介绍 Dubbo 自定义标签解析相关内容,其中我们自定义的 XML 标签 <dubbo:service /> 会被解析为 ServiceBean 对象(传送门:Dubbo ...
- 【Dubbo源码阅读系列】之 Dubbo SPI 机制
最近抽空开始了 Dubbo 源码的阅读之旅,希望可以通过写文章的方式记录和分享自己对 Dubbo 的理解.如果在本文出现一些纰漏或者错误之处,也希望大家不吝指出. Dubbo SPI 介绍 Java ...
- Dubbo源码阅读顺序
转载: https://blog.csdn.net/heroqiang/article/details/85340958 Dubbo源码解析之配置解析篇,主要内容是<dubbo:service/ ...
- Dubbo源码阅读-服务导出
Dubbo服务导出过程始于Spring容器发布刷新事件,Dubbo在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可分为三个部分,第一部分是前置工作,主要用于检查参数,组装URL.第二部分是导出服 ...
- dubbo源码阅读之SPI
dubbo SPI SPI,全程Service Provider interface, java中的一种借口扩展机制,将借口的实现类注明在配置文件中,程序在运行时通过扫描这些配置文件从而获取全部的实现 ...
- dubbo源码阅读之自适应扩展
自适应扩展机制 刚开始看代码,其实并不能很好地理解dubbo的自适应扩展机制的作用,我们不妨先把代码的主要逻辑过一遍,梳理一下,在了解了代码细节之后,回过头再来思考自适应扩展的作用,dubbo为什么要 ...
- 【Dubbo源码阅读系列】之 Dubbo XML 配置加载
今天我们来谈谈 Dubbo XML 配置相关内容.关于这部分内容我打算分为以下几个部分进行介绍: Dubbo XML Spring 自定义 XML 标签解析 Dubbo 自定义 XML 标签解析 Du ...
随机推荐
- 在android系统调试中使用tinyalsa命令【转】
本文转载自:http://blog.csdn.net/tangdexi112/article/details/17579021 我们在进行音频调试的时候,需要使用tinymix.tinyplay.ti ...
- Android+Jquery Mobile学习系列(7)-保险人信息
[保险人管理]是这个APP最重要的功能,用于保存保险客户的数据,给后面的功能提供数据支撑. 简单说说[保险人管理]功能:主要就是增.删.改.查四个功能,在新增和修改的时候不仅可以保存保险人的姓名.身份 ...
- Node.js安全清单
前言 安全性,总是一个不可忽视的问题.许多人都承认这点,但是却很少有人真的认真地对待它.所以我们列出了这个清单,让你在将你的应用部署到生产环境来给千万用户使用之前,做一个安全检查. 以下列出的安全项, ...
- etcd数据备份与恢复验证
一.单机 说明:执行etcd备份数据的恢复的机器必须和原先etcd所在机器一致 1.单机备份 etcdctl --endpoints="https://10.25.72.62:2379&qu ...
- thinkphp的ip地址定位
在WEB应用中,根据IP地址定位和记录相关访问日志也是非常常见的需求,在ThinkPHP中你可以轻松的实现IP地址获取和定位. 获取扩展类库 可以在官网的http://www.thinkphp.cn/ ...
- nodejs express开发
用NodeJS+Express开发WEB应用---第一篇 大漠穷秋2014-03-28 预热 为了对后面的内容理解更加透彻,推荐首先阅读下面这篇很好的文章: http://www.nodebeginn ...
- maven添加本地jar包的方法
1.将一个本地的jar包随便放在一个放入本地文件夹中 (文件夹位置 和 jar包名称都随意) 例:F:\java\repository\a 文件夹下,名称为:icepdf-core-6.0.jar 2 ...
- B - Alyona and mex(构造)
Problem description Alyona's mother wants to present an array of n non-negative integers to Alyona. ...
- wcf 错误:无法加载或初始化请求的服务提供程序
解决办法:cmd netsh winsock reset 恢复网络编程接口
- C#开发微信公众号——网页开发之微信网页授权
首先咱们先看下公众号的文档里面的介绍 上述图片的文字描述就是讲述了网页授权有什么用,就是为了获取微信用户的基本信息:授权回调域名的规范,说到域名回调的事情就不得不提一下设置网页授权域名 最好将这三个域 ...