- 浏览: 514523 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (563)
- 工作经验 (12)
- 数据库 (13)
- Servlet (10)
- Struts2 (1)
- Spring (25)
- Eclipse (5)
- Hibernate (5)
- Eclips (8)
- HTTP (7)
- J2EE (21)
- EHcache (1)
- HTML (11)
- 工具插件使用 (20)
- JPA (2)
- 杂谈 (17)
- 数据结构与算法 (3)
- Cloud Foundry (1)
- 安全 (10)
- J2SE (57)
- SQL (9)
- DB2 (6)
- 操作系统 (2)
- 设计模式 (1)
- 版本代码管理工具 (13)
- 面试 (10)
- 代码规范 (3)
- Tomcat (12)
- Ajax (5)
- 异常总结 (11)
- REST (2)
- 云 (2)
- RMI (3)
- SOA (1)
- Oracle (12)
- Javascript (20)
- jquery (7)
- JSP自定义标签 (2)
- 电脑知识 (5)
- 浏览器 (3)
- 正则表达式 (3)
- 建站解决问题 (38)
- 数据库设计 (3)
- git (16)
- log4j (1)
- 每天100行代码 (1)
- socket (0)
- java设计模式 耿祥义著 (0)
- Maven (14)
- ibatis (7)
- bug整理 (2)
- 邮件服务器 (8)
- Linux (32)
- TCP/IP协议 (5)
- java多线程并发 (7)
- IO (1)
- 网页小工具 (2)
- Flash (2)
- 爬虫 (1)
- CSS (6)
- JSON (1)
- 触发器 (1)
- java并发 (12)
- ajaxfileupload (1)
- js验证 (1)
- discuz (2)
- Mysql (14)
- jvm (2)
- MyBatis (10)
- POI (1)
- 金融 (1)
- VMWare (0)
- Redis (4)
- 性能测试 (2)
- PostgreSQL (1)
- 分布式 (2)
- Easy UI (1)
- C (1)
- 加密 (6)
- Node.js (1)
- 事务 (2)
- zookeeper (3)
- Spring MVC (2)
- 动态代理 (3)
- 日志 (2)
- 微信公众号 (2)
- IDEA (1)
- 保存他人遇到的问题 (1)
- webservice (11)
- memcached (3)
- nginx (6)
- 抓包 (1)
- java规范 (1)
- dubbo (3)
- xwiki (1)
- quartz (2)
- 数字证书 (1)
- spi (1)
- 学习编程 (6)
- dom4j (1)
- 计算机系统知识 (2)
- JAVA系统知识 (1)
- rpcf (1)
- 单元测试 (2)
- php (1)
- 内存泄漏cpu100%outofmemery (5)
- zero_copy (2)
- mac (3)
- hive (3)
- 分享资料整理 (0)
- 计算机网络 (1)
- 编写操作系统 (1)
- springboot (1)
最新评论
-
masuweng:
亦论一次OutOfMemoryError的定位与解错 -
变脸小伙:
引用[color=red][/color]百度推广中运用的技术 ...
Spring 3 mvc中返回pdf,json,xml等不同的view -
Vanillva:
不同之处是什么??
Mybatis中的like查询 -
thrillerzw:
转了。做个有理想的程序员
有理想的程序员必须知道的15件事 -
liujunhui1988:
觉得很有概括力
15 个必须知道的 Java 面试问题(2年工作经验)
源:http://blog.csdn.net/fenglibing/article/details/7083526
评:
这篇关于SPI的文章是在blogspot上面,,大多数人访问不了,就贴在这里,比较好懂。
From ServiceLoader javadoc: A service is a well-known set of interfaces and classes. A service provider is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself.
Since JDK 6, a simple service-provider loading facility is implemented. As is suggested it is simple, you cannot understand that implementation as a complex system for implementing plugins for your application, but can help you in many situations where you want implementations of a service could be discovered by other module automatically.
What I really like about using JDK Services is that your services do not have any dependency to any class. Moreover for registering a new implementation of a service, you just have to put jar file into classpath and nothing more.
Now I will explain the service we are going to implement, and then I will show you how to code it.
We want to implement a system that depending on kind of structured input (comma-separated value, tab-separated value, ...) returns a String[] of each value; so for example you can receive input a,b,c,dor 1<tab>2<tab>3<tab>4 and the system should return an array with [a, b, c, d] or [1, 2, 3, 4].
So our system will have three Java projects.
One defining service contract (an interface) and, because of teaching purpose, a main class where internet media type, for example text/csv, is received with input data. Then using a factory class that I have created, it will ask which registered service can transform input to String[].
And two projects each one implementing a service following defined contract, one for comma-separated values and another one for tab-separated values.
Let's see the code:
Main project (reader) is composed by an interface, a main class and a factory class.
The most important part is Decode interface which defines service contract.
[java] view plaincopy
public interface Decode {
boolean isEncodingNameSupported(String encodingName);
String[] getContent(String data);
}
Two operations are defined, one that returns if service supports given input, and another that transforms data to String[].
DecodeFactory class is responsible for finding an implementation service that supports required encoding. In fact, this class encapsulates java.util.ServiceLoader calls. ServiceLoader class is in charge of load registered services.
[java] view plaincopy
public class DecodeFactory {
private static ServiceLoader decodeSetLoader = ServiceLoader.load(Decode.class);
public static Decode getDecoder(String encodingName) throws UnsupportedEncodingException {
for (Decode decode : decodeSetLoader) {
if(decode.isEncodingNameSupported(encodingName)) {
return decode;
}
}
throw new UnsupportedEncodingException();
}
}
At line 3 we are loading all services that are registered in classpath. At line 7 we only iterate through all services asking if given encoding name is supported.
And finally main class.
[java] view plaincopy
public class App {
public static void main(String[] args) throws UnsupportedEncodingException {
String encodeName = args[0];
String data = args[1];
Decode decoder = DecodeFactory.getDecoder(encodeName);
System.out.println(Arrays.toString(decoder.getContent(data)));
}
}
And now if you run this class with java -jar reader.jar "text/cvs" "a, b, c, d", anUnsupportedEncodingException will be thrown. Now we are going to implement our first service. Note that reader project will not be modified nor recompiled.
First service we are going to implement is one that can support comma-separated values encoding. Only one class and one file are important.
CSV class is an implementation of Decode interface and transforms comma-separated values.
[java] view plaincopy
public class CSVDecoder implements Decode {
private static final String DELIMITER = Character.toString(DecimalFormatSymbols.getInstance().getPatternSeparator());
public boolean isEncodingNameSupported(String encodingName) {
return "text/csv".equalsIgnoreCase(encodingName.trim());
}
public String[] getContent(String data) {
List values = new LinkedList();
StringTokenizer parser = new StringTokenizer(data, DELIMITER);
while(parser.hasMoreTokens()) {
values.add(parser.nextToken());
}
return values.toArray(new String[values.size()]);
}
}
As you can see a simple StringTokenizer class. Only take care that this class is Locale sensitive, countries where comma (,) is used as decimal delimiter, separation character is semicolon (;).
And next important file is a file that is placed into META-INF. This file contains a pointer to service implementation class.
This file should be in META-INF/services and should be called as interface full qualified name. In this case org.alexsotob.reader.Decode. And its content should be service implementation full qualified name.
[plain] view plaincopy
org.alexsotob.reader.csv.CSVDecoder #Comma-separated value decode.
And now you can package this project, and you can reexecute reader project but with generated jar(csv.jar) into classpath. And now output will be an array with a, b, c and d characters instead of unsupported exception.
See that reader project has not been modified and its behaviour has been changed. Now you can develop new implementations for decoding new inputs, and you should only take care of copying them into classpath.
Only take care that all services should have a default constructor with no arguments.
And for those who use Spring Framework, Services are also supported through three differentFactoryBeans, ServiceFactoryBean, ServiceListFactoryBean, ServiceLoaderFactoryBean.
As I have noted at start of this post, JDK services is a simple (yet powerful) solution if you need to create a simple plugins system. In my case it has been enough with JDK services, and I have never required more complex structure; but in case you are thinking about a complete plugin solution you can use JPF that offers a solution like Eclipse plugins, or even OSGI.
I wish you have found this post useful and now you know (if you didn't know yet), an easy solution to develop modules that are plugged and play.
Download Main Project: https://github.com/downloads/maggandalf/Blog-Examples/reader.zip
Download Comma-Separated Values Service Project: https://github.com/downloads/maggandalf/Blog-Examples/csvDec.zip
Download Tab-Separated Values Service Project: https://github.com/downloads/maggandalf/Blog-Examples/tsvDec.zip
Music: http://www.youtube.com/watch?v=5cV_sIdpXeA&feature=related
原文链接:http://alexsotob.blogspot.com/2011/11/en-ti-puedo-ver-la-libertad-tu-me-haces.html
评:
这篇关于SPI的文章是在blogspot上面,,大多数人访问不了,就贴在这里,比较好懂。
From ServiceLoader javadoc: A service is a well-known set of interfaces and classes. A service provider is a specific implementation of a service. The classes in a provider typically implement the interfaces and subclass the classes defined in the service itself.
Since JDK 6, a simple service-provider loading facility is implemented. As is suggested it is simple, you cannot understand that implementation as a complex system for implementing plugins for your application, but can help you in many situations where you want implementations of a service could be discovered by other module automatically.
What I really like about using JDK Services is that your services do not have any dependency to any class. Moreover for registering a new implementation of a service, you just have to put jar file into classpath and nothing more.
Now I will explain the service we are going to implement, and then I will show you how to code it.
We want to implement a system that depending on kind of structured input (comma-separated value, tab-separated value, ...) returns a String[] of each value; so for example you can receive input a,b,c,dor 1<tab>2<tab>3<tab>4 and the system should return an array with [a, b, c, d] or [1, 2, 3, 4].
So our system will have three Java projects.
One defining service contract (an interface) and, because of teaching purpose, a main class where internet media type, for example text/csv, is received with input data. Then using a factory class that I have created, it will ask which registered service can transform input to String[].
And two projects each one implementing a service following defined contract, one for comma-separated values and another one for tab-separated values.
Let's see the code:
Main project (reader) is composed by an interface, a main class and a factory class.
The most important part is Decode interface which defines service contract.
[java] view plaincopy
public interface Decode {
boolean isEncodingNameSupported(String encodingName);
String[] getContent(String data);
}
Two operations are defined, one that returns if service supports given input, and another that transforms data to String[].
DecodeFactory class is responsible for finding an implementation service that supports required encoding. In fact, this class encapsulates java.util.ServiceLoader calls. ServiceLoader class is in charge of load registered services.
[java] view plaincopy
public class DecodeFactory {
private static ServiceLoader decodeSetLoader = ServiceLoader.load(Decode.class);
public static Decode getDecoder(String encodingName) throws UnsupportedEncodingException {
for (Decode decode : decodeSetLoader) {
if(decode.isEncodingNameSupported(encodingName)) {
return decode;
}
}
throw new UnsupportedEncodingException();
}
}
At line 3 we are loading all services that are registered in classpath. At line 7 we only iterate through all services asking if given encoding name is supported.
And finally main class.
[java] view plaincopy
public class App {
public static void main(String[] args) throws UnsupportedEncodingException {
String encodeName = args[0];
String data = args[1];
Decode decoder = DecodeFactory.getDecoder(encodeName);
System.out.println(Arrays.toString(decoder.getContent(data)));
}
}
And now if you run this class with java -jar reader.jar "text/cvs" "a, b, c, d", anUnsupportedEncodingException will be thrown. Now we are going to implement our first service. Note that reader project will not be modified nor recompiled.
First service we are going to implement is one that can support comma-separated values encoding. Only one class and one file are important.
CSV class is an implementation of Decode interface and transforms comma-separated values.
[java] view plaincopy
public class CSVDecoder implements Decode {
private static final String DELIMITER = Character.toString(DecimalFormatSymbols.getInstance().getPatternSeparator());
public boolean isEncodingNameSupported(String encodingName) {
return "text/csv".equalsIgnoreCase(encodingName.trim());
}
public String[] getContent(String data) {
List values = new LinkedList();
StringTokenizer parser = new StringTokenizer(data, DELIMITER);
while(parser.hasMoreTokens()) {
values.add(parser.nextToken());
}
return values.toArray(new String[values.size()]);
}
}
As you can see a simple StringTokenizer class. Only take care that this class is Locale sensitive, countries where comma (,) is used as decimal delimiter, separation character is semicolon (;).
And next important file is a file that is placed into META-INF. This file contains a pointer to service implementation class.
This file should be in META-INF/services and should be called as interface full qualified name. In this case org.alexsotob.reader.Decode. And its content should be service implementation full qualified name.
[plain] view plaincopy
org.alexsotob.reader.csv.CSVDecoder #Comma-separated value decode.
And now you can package this project, and you can reexecute reader project but with generated jar(csv.jar) into classpath. And now output will be an array with a, b, c and d characters instead of unsupported exception.
See that reader project has not been modified and its behaviour has been changed. Now you can develop new implementations for decoding new inputs, and you should only take care of copying them into classpath.
Only take care that all services should have a default constructor with no arguments.
And for those who use Spring Framework, Services are also supported through three differentFactoryBeans, ServiceFactoryBean, ServiceListFactoryBean, ServiceLoaderFactoryBean.
As I have noted at start of this post, JDK services is a simple (yet powerful) solution if you need to create a simple plugins system. In my case it has been enough with JDK services, and I have never required more complex structure; but in case you are thinking about a complete plugin solution you can use JPF that offers a solution like Eclipse plugins, or even OSGI.
I wish you have found this post useful and now you know (if you didn't know yet), an easy solution to develop modules that are plugged and play.
Download Main Project: https://github.com/downloads/maggandalf/Blog-Examples/reader.zip
Download Comma-Separated Values Service Project: https://github.com/downloads/maggandalf/Blog-Examples/csvDec.zip
Download Tab-Separated Values Service Project: https://github.com/downloads/maggandalf/Blog-Examples/tsvDec.zip
Music: http://www.youtube.com/watch?v=5cV_sIdpXeA&feature=related
原文链接:http://alexsotob.blogspot.com/2011/11/en-ti-puedo-ver-la-libertad-tu-me-haces.html
发表评论
-
NullPointerException丢失异常堆栈信息
2017-09-25 11:23 1016源:http://blog.csdn.net/taotao4/ ... -
JAVA实现SFTP实例
2016-04-20 19:10 487源:http://www.cnblogs.com/chen19 ... -
Axis1.x WebService开发指南—目录索引
2015-11-30 15:54 641源:http://www.cnblogs.com/hoojo/ ... -
CXF WebService整合Spring
2015-11-30 15:50 503源:http://www.cnblogs.com/hoojo/ ... -
几种常用的webservice客户端和spring集成的方法
2015-11-30 15:47 562源:http://my.oschina.net/zimingf ... -
serialVersionUID的作用
2015-11-08 15:27 580源:http://www.cnblogs.com/gu ... -
(未解决问题)Tomcat undeploy does not remove web application artifacts
2015-09-18 11:26 554源:http://stackoverflow.com/ques ... -
使用 VisualVM 进行性能分析及调优
2015-08-25 21:26 494源:http://www.ibm.com/develo ... -
使用Java VisualVM监控远程JVM
2015-08-25 21:25 744源:http://blog.163.com/liuyb_942 ... -
获取spring的ApplicationContext几种方式
2015-06-24 15:35 699源:http://blog.sina.com.cn/s/blo ... -
转:Java 理论与实践: 用 JMX 检测应用程序
2015-06-17 21:26 418源:http://www.ibm.com/developerw ... -
如何使用webservice
2015-04-09 15:47 5271:到http://cxf.apache.org/downlo ... -
spring获取webapplicationcontext,applicationcontext几种方法详解
2015-04-02 16:38 467源:http://www.blogjava.net/Todd/ ... -
【java规范】Java spi机制浅谈
2015-01-27 10:52 453源:http://singleant.iteye.com/bl ... -
REGISTRY KEY 'SOFTWARE\JAVASOFT\JAVA RUNTIME ENVIRONMENT\CURRENTVERSION'错误
2015-01-21 20:17 590源:http://www.blogjava.net/tomor ... -
Spring线程池开发实战
2014-12-12 10:44 499源:http://blog.csdn.net/chszs/ar ... -
在web.xml下配置error-page
2014-07-18 16:13 429源:http://ysj5125094.iteye.com/b ... -
Write your own Java server
2014-05-14 11:47 742源:http://srcode.org/2014/05/11/ ... -
什么是流
2013-04-05 17:41 958源:http://www.iteye.com/topic/3 ... -
什么是J2EE,包括哪些规范!
2013-01-17 14:17 820源:http://blog.163.com/xiaopeng ...
相关推荐
This release contains Java API for XML Processing (JAXP) 1.4.5, supports Java Architecture for XML Binding (JAXB) 2.2.3, and supports Java API for XML Web Services (JAX-WS) 2.2.4. ...
The JavaFX APIs define a set of user-interface controls, graphics, media, and web packages for developing rich client applications. These APIs are in modules whose names start with javafx. Java SE ...
Using the Intent Service to Simplify the Earthquake Update Service Chapter 10: Expanding the User Experience Introducing the Action Bar Adding an Action Bar to the Earthquake Monitor Creating and ...
Table of Contents Preface 1 Chapter 1: Getting Started with Geronimo 7 Motivation behind the Geronimo project 7 ...Using the Java Logging API 333 Using the SLF4j logging adapter ...
- **Custom Document ID Provider:** Implementing a custom provider to generate unique IDs. #### Site Templates - **Native Site Definitions:** Predefined templates included with SharePoint. - **Custom ...
dbExpress driver for Oracle is a cross-platform solution for developing applications using various IDEs: RAD Studio, Delphi, C++Builder on Windows and Mac OS X for both x86 and x64 platforms....
1. a book Developing Flex Applications 2. a web page viewer for doc88 ebt 3. a DDA downloader for doc88.com CONTENTS PART I: Presenting Flex CHAPTER 1: Introducing Flex. . . . . . . . . . . . . . ...
18)..Fixed: Possible "Unit XYZ was compiled with a different version of ABC" when using packages 19)..Fixed: FastMM shared MM compatibility 20)..Fixed: Minor bugs in stack tracing (which usually ...