Hivemind简介
1. 一个完整的例子
a) 目录结构
|--
| |--META-INF
| |--
| |--hivemodule.xml
| |--log4j.properties
|
|--nick
|--Test.java
|--IHello.java
|--IMessageBuilder.java
|--impl
|--HelloImpl.java
|--MessageBuilderImpl.java
b) Hivemodule.xml
<?xml version="1.0"?>
<module id="nick" version=" 1.0.0 " package="nick">
<service-point id="IHello" interface="IHello">
<invoke-factory>
<construct class="impl.HelloImpl" />
</invoke-factory>
</service-point>
<service-point id="IMessageBuilder" interface="IMessageBuilder">
<create-instance class="impl.MessageBuilderImpl" />
</service-point>
</module>
注:service是hivemind里面的一个核心概念,他的含义与Spring里面的bean类似。这里定义了两个service,我们可以通过<invoke-factory>或者<create-instance>来指定该接口所对应的实现类。这两个标签都是用于指定可实例话的类,他们的区别是,invoke-factory的可配性更多一些,也就是说,他可以更大限度的对实例化过程进行定制。
c) 测试类(Test)
package nick;
/**
* @author cenyongh@gmail.com
*/
public class Test {
public static void main(String[] args) {
Registry registry = RegistryBuilder.constructDefaultRegistry();
IHello hello = (IHello) registry.getService(IHello.class);
hello.hello("nick");
}
}
注:这里唯一要留意的就是Hivemind的程序入口是Registry类,上面的代码演示了如何得到一个Registry引用,并且如何从该Registry得到我们想要的事例。
d) 自动编织
Hivemind通过setXXX()方法来实现自动的依赖注入。
2. Service Override
有的时候你需要替换掉某个service的默认实现。这可以通过<implementation>来实现。
<?xml version="1.0"?>
<module id="nick" version=" 1.0.0 " package="nick">
<service-point id="IHello" interface="IHello">
<invoke-factory>
<construct class="impl.HelloImpl" />
</invoke-factory>
</service-point>
<service-point id="IMessageBuilder" interface="IMessageBuilder">
<create-instance class="impl.MessageBuilderImpl" />
</service-point>
<implementation service-id="IMessageBuilder">
<create-instance class="impl.MessageBuilderImpl2"/>
</implementation>
</module>
注:在这里,我们定义了一个id为IMessageBuilder的service,并通过嵌套的create-instance标记定义了实现类。但是后续的implementation标签,则通过指定service-id的方式,替换了该默认实现,这样的一个直接后果就是,所有引用IMessageBuilder的地方都将使用impl.MessageBuilderImpl2这个新的实现类。
3. ServiceImplementationFactory
在定义<service>时,我们可以通过<invoke-factory>或者<create-instance>来创建事例。而如果使用<invoke-factory>的话,则可以通过指定一个service-id,来指定某一个ServiceImplementationFactory实例,来负责实例的创建。
a) Hivemodule.xml
<?xml version="1.0"?>
<module id="nick" version=" 1.0.0 " package="nick">
<service-point id="myFactory" interface="org.apache.hivemind.ServiceImplementationFactory">
<create-instance class="MyFactory" />
</service-point>
<service-point id="IHello" interface="IHello">
<invoke-factory service-id="myFactory">
<construct class="impl.HelloImpl" />
</invoke-factory>
</service-point>
</module>
b) ServiceImplementationFactory
public class MyFactory implements ServiceImplementationFactory {
public Object createCoreServiceImplementation(
ServiceImplementationFactoryParameters arg0) {
Module module = arg0.getInvokingModule();
ElementImpl para = (ElementImpl) arg0.getFirstParameter();
Class klass = module.resolveType(para.getAttributeValue("class"));
try {
Object inst = klass.newInstance();
return inst;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
注:由于我们在module上面定义了module所属的主package,所以在<construct>标签里面,我们的class属性里面并不是类的完整包名。所以,这里需要用module来得到完整的类名。上述方案可以正确的创建实例,但是并没有进行依赖注入。默认情况下,hivemind使用单子模式来创建实例,而单子的管理则不是在ServiceImplementationFactory里实现,而是由外部负责调用ServiceImplementationFactory的类完成。
4. Interceptor
a) 语法:
<service-point id="myInterceptorFactory"
interface="org.apache.hivemind.ServiceInterceptorFactory">
<create-instance class="MyInterceptorFactory" />
</service-point>
<service-point id="IHello" interface="IHello">
<create-instance class="impl.HelloImpl" />
<interceptor service-id="myInterceptorFactory" />
</service-point>
注:Interceptor也是一个service,它需要实现ServiceInterceptorFactory。通过<interceptor>声明所使用的Interceptor。
b) Interceptor实现
public class MyInterceptorFactory implements ServiceInterceptorFactory {
public void createInterceptor(InterceptorStack stack,
Module invokingModule, List parameters) {
Object inst = stack.peek();
ClassPool pool = ClassPool.getDefault();
try {
CtClass superClass = pool.get(inst.getClass().getCanonicalName());
CtClass interceptor = pool.makeClass(inst.getClass().getCanonicalName()
+ "inter");
interceptor.setSuperclass(superClass);
CtMethod[] methods = superClass.getDeclaredMethods();
for (CtMethod method : methods) {
CtMethod nm = CtNewMethod.copy(method, interceptor, null);
interceptor.addMethod(nm);
nm.setBody("{System.out.println(/"[BEFORE]" + method.getName()
+ "/");super." + method.getName()
+ "($$);System.out.println(/"[AFTER]"
+ method.getName() + "/");}");
}
stack.push(interceptor.toClass().newInstance());
} catch (Exception e) {
e.printStackTrace();
}
}
}
注:以上代码我们做了以下几件事。第一我们得到了需要被Intercept的类。然后利用Javassist来创建一个该类的子类。第三,由于我们不一定有被Intercept类的源代码,所以,上述代码所采用的方式是,对被Intercept类的每个声明的方法复制其方法签名,然后通过setBody()方式替换其内部实现。最后,就是把Javassist创建的子类实例化,并压到InterceptorStack当中。上述代码做的就是一个Logger。
Hivemind简介相关推荐
- c语言中ioc有什么作用,IOC简介
一.IOC简介 IOC-全称Inversion of Control,中文解释:控制反转.另外,IOC又称DI(全称)Dependency Injection,中文解释:依赖注入. 呵呵,这些名词搞得 ...
- java开源工具简介(2)
java开源工具简介(2) OpenCms [Java开源 CMS系统] OpenCms是一个J2EE的产品,它是用Java写成的.它和Tomcat捆绑在一起.但是也能够使用ATG Dynamo.We ...
- etcd 笔记(01)— etcd 简介、特点、应用场景、常用术语、分布式 CAP 理论、分布式原理
1. etcd 简介 etcd 官网定义: A highly-available key value store for shared configuration and service discov ...
- Docker学习(一)-----Docker简介与安装
一.Docker介绍 1.1什么是docker Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源 Docker可以让开发者打包他们的应用以及依赖包到一个轻量级,可移植 ...
- 【Spring】框架简介
[Spring]框架简介 Spring是什么 Spring是分层的Java SE/EE应用full-stack轻量级开源框架,以IOC(Inverse Of Control:反转控制)和AOP(Asp ...
- TensorRT简介
TensorRT 介绍 引用:https://arleyzhang.github.io/articles/7f4b25ce/ 1 简介 TensorRT是一个高性能的深度学习推理(Inference) ...
- 谷粒商城学习笔记——第一期:项目简介
一.项目简介 1. 项目背景 市面上有5种常见的电商模式 B2B.B2C.C2B.C2C.O2O B2B 模式(Business to Business),是指商家和商家建立的商业关系.如阿里巴巴 B ...
- 通俗易懂的Go协程的引入及GMP模型简介
本文根据Golang深入理解GPM模型加之自己的理解整理而来 Go协程的引入及GMP模型 一.协程的由来 1. 单进程操作系统 2. 多线程/多进程操作系统 3. 引入协程 二.golang对协程的处 ...
- Linux 交叉编译简介
Linux 交叉编译简介 主机,目标,交叉编译器 主机与目标 编译器是将源代码转换为可执行代码的程序.像所有程序一样,编译器运行在特定类型的计算机上,输出的新程序也运行在特定类型的计算机上. 运行编译 ...
最新文章
- 编译android不再需要jdk1.5
- bigdecimal为0 xml不走_爱情不能够接受谎言的星座,天蝎座容忍度为0,发现将失去彼此...
- springMVC之Interceptor拦截器
- BC30138: 无法在路径“C:\WINDOWS\TEMP\”中创建临时文件: 拒绝访问。
- springboot 与shiro整合
- 2021年中国地下采矿机械市场趋势报告、技术动态创新及2027年市场预测
- String类两种实例化方式的区别
- 如何用一台计算机控制多台计算机,怎么用一套鼠标键盘操作两台或多台电脑?...
- 聚类分析原理及R语言实现过程
- angular对象简单介绍
- 在线QQ客服链接,只添加 qq号
- 【C】狐狸找兔子问题
- CentOS6安装rpm时报错“Cannot find a valid baseurl for repo: centos-sclo-rh“的解决办法
- jQuery读取JSON数据(jQuery调用JSON数据学习第二天)
- 基于CST相控阵天线快速设计方法
- PS字体加粗的小方法、、
- win32游戏开发(2) --连连看游戏制作(vc++版)
- PCB如何入门---一些经验与教训
- 雕刻效果的实现【OpenCV+QT】
- prescan安装包(8.5/2019.2版本)下载
热门文章
- parent()与parents()的区别
- 由Github迁移到GitCafe
- gitcafe: programming everyday
- 2014秋C++ 狗逮耗子之“开口说英语”
- 因式分解法解一元二次方程
- html字母显示红色,css中字体红色如何实现?
- YoloV5+ROS2直接发布出物品坐标
- 系统服务器 lis6.0,LIS系统条形码生成接口说明(Service)
- 硬件知识:32-64位电脑?操作系统?软件?
- Altium Allegro PADS到底该选哪个EDA设计软件