Introduction to the Service Provider Interfaces--官方文档
地址:https://docs.oracle.com/javase/tutorial/sound/SPI-intro.html
What Are Services?
Services are units of sound-handling functionality that are automatically available when an application program makes use of an implementation of the Java Sound API. They consist of objects that do the work of reading, writing, mixing, processing, and converting audio and MIDI data. An implementation of the Java Sound API generally supplies a basic set of services, but mechanisms are also included in the API to support the development of new sound services by third-party developers (or by the vendor of the implementation itself). These new services can be "plugged into" an existing installed implementation to expand its functionality without requiring a new release. In the Java Sound API architecture, third-party services are integrated into the system in such a way that an application program's interface to them is the same as the interface to the "built-in" services. In some cases, application developers who use thejavax.sound.sampled
and javax.sound.midi
packages might not even be aware that they are employing third-party services.
Examples of potential third-party, sampled-audio services include:
- Sound file readers and writers
- Converters that translate between different audio data formats
- New audio mixers and input/output devices, whether implemented purely in software, or in hardware with a software interface
Third-party MIDI services might consist of:
- MIDI file readers and writers
- Readers for various types of soundbank files (which are often specific to particular synthesizers)
- MIDI-controlled sound synthesizers, sequencers, and I/O ports, whether implemented purely in software, or in hardware with a software interface
How Services Work
The javax.sound.sampled
and javax.sound.midi
packages provide functionality to application developers who wish to include sound services in their application programs. These packages are for consumers of sound services, providing interfaces to get information about, control, and access audio and MIDI services. In addition, the Java Sound API also supplies two packages that define abstract classes to be used by providers of sound services: the javax.sound.sampled.spi
and javax.sound.midi.spi
packages.
Developers of new sound services implement concrete subclasses of the appropriate classes in the SPI packages. These subclasses, along with any additional classes required to support the new service, are placed in a Java Archive (JAR) archive file with a description of the included service or services. When this JAR file is installed in the user's CLASSPATH
, the runtime system automatically makes the new service available, extending the functionality of the Java platform's runtime system.
Once the new service is installed, it can be accessed just like any previously installed service. Consumers of services can get information about the new service, or obtain instances of the new service class itself, by invoking methods of the AudioSystem
and MidiSystem
classes (in the javax.sound.sampled
and javax.sound.midi
packages, respectively) to return information about the new services, or to return instances of new or existing service classes themselves. Application programs need not—and should not—reference the classes in the SPI packages (and their subclasses) directly to make use of the installed services.
For example, suppose a hypothetical service provider called Acme Software, Inc. is interested in supplying a package that allows application programs to read a new format of sound file (but one whose audio data is in a standard data format). The SPI class AudioFileReader
can be subclassed into a class called, say, AcmeAudioFileReader
. In the new subclass, Acme would supply implementations of all the methods defined in AudioFileReader
; in this case there are only two methods (with argument variants), getAudioFileFormat
andgetAudioInputStream
. Then when an application program attempted to read a sound file that happened to be in Acme's file format, it would invoke methods of the AudioSystem
class injavax.sound.sampled
to access the file and information about it. The methods AudioSystem.getAudioInputStream
and AudioSystem.getAudioFileFormat
provide a standard API to read audio streams; with the AcmeAudioFileReader
class installed, this interface is extended to support the new file type transparently. Application developers don't need direct access to the newly registered SPI classes: the AudioSystem
object methods pass the query on to the installed AcmeAudioFileReader
class.
What's the point of having these "factory" classes? Why not permit the application developer to get access directly to newly provided services? That is a possible approach, but having all management and instantiation of services pass through gatekeeper system objects shields the application developer from having to know anything about the identity of installed services. Application developers just use services of value to them, perhaps without even realizing it. At the same time this architecture permits service providers to effectively manage the available resources in their packages.
Often the use of new sound services is transparent to the application program. For example, imagine a situation where an application developer wants to read in a stream of audio from a file. Assuming that thePathName
identifies an audio input file, the program does this:
File theInFile = new File(thePathName);
AudioInputStream theInStream = AudioSystem.getAudioInputStream(theInFile);
Behind the scenes, the AudioSystem
determines what installed service can read the file and asks it to supply the audio data as an AudioInputStream
object. The developer might not know or even care that the input audio file is in some new file format (such as Acme's), supported by installed third-party services. The program's first contact with the stream is through theAudioSystem
object, and all its subsequent access to the stream and its properties are through the methods of AudioInputStream
. Both of these are standard objects in thejavax.sound.sampled
API; the special handling that the new file format may require is completely hidden.
How Providers Prepare New Services
Service providers supply their new services in specially formatted JAR files, which are to be installed in a directory on the user's system where the Java runtime will find them. JAR files are archive files, each containing sets of files that might be organized in hierarchical directory structures within the archive. Details about the preparation of the class files that go into these archives are discussed in the next few pages, which describe the specifics of the audio and MIDI SPI packages; here we'll just give an overview of the process of JAR file creation.
The JAR file for a new service or services should contain a class file for each service supported in the JAR file. Following the Java platform's convention, each class file has the name of the newly defined class, which is a concrete subclass of one of the abstract service provider classes. The JAR file also must include any supporting classes required by the new service implementation. So that the new service or services can be located by the runtime system's service provider mechanism, the JAR file must also contain special files (described below) that map the SPI class names to the new subclasses being defined.
To continue from our example above, say Acme Software, Inc. is distributing a package of new sampled-audio services. Let's suppose this package consists of two new services:
- The
AcmeAudioFileReader
class, which was mentioned above, and which is a subclass ofAudioFileReader
- A subclass of
AudioFileWriter
calledAcmeAudioFileWriter
, which will write sound files in Acme's new format
Starting from an arbitrary directory—let's call it /devel
—where we want to do the build, we create subdirectories and put the new class files in them, organized in such a manner as to give the desired pathname by which the new classes will be referenced:
com/acme/AcmeAudioFileReader.class
com/acme/AcmeAudioFileWriter.class
In addition, for each new SPI class being subclassed, we create a mapping file in a specially named directory META-INF/services
. The name of the file is the name of the SPI class being subclassed, and the file contains the names of the new subclasses of that SPI abstract class.
We create the file
META-INF/services/javax.sound.sampled.spi.AudioFileReader
which consists of
# Providers of sound file-reading services
# (a comment line begins with a pound sign)
com.acme.AcmeAudioFileReader
and also the file
META-INF/services/javax.sound.sampled.spi.AudioFileWriter
which consists of
# Providers of sound file-writing services
com.acme.AcmeAudioFileWriter
Now we run jar
from any directory with the command line:
jar cvf acme.jar -C /devel .
The -C
option causes jar
to switch to the /devel
directory, instead of using the directory in which the command is executed. The final period argument instructs jar
to archive all the contents of that directory (namely, /devel
), but not the directory itself.
This run will create the file acme.jar
with the contents:
com/acme/AcmeAudioFileReader.class
com/acme/AcmeAudioFileWriter.class
META-INF/services/javax.sound.sampled.spi.AudioFileReader
META-INF/services/javax.sound.sampled.spi.AudioFileWriter
META-INF/Manifest.mf
The file Manifest.mf,
which is generated by the jar
utility itself, is a list of all the files contained in the archive.
How Users Install New Services
For end users (or system administrators) who wish to get access to a new service through their application programs, installation is simple. They place the provided JAR file in a directory in theirCLASSPATH.
Upon execution, the Java runtime will find the referenced classes when needed.
It's not an error to install more than one provider for the same service. For example, two different service providers might supply support for reading the same type of sound file. In such a case, the system arbitrarily chooses one of the providers. Users who care which provider is chosen should install only the desired one.
Introduction to the Service Provider Interfaces--官方文档的更多相关文章
- 《Spring 5官方文档》 Spring AOP的经典用法
原文链接 在本附录中,我们会讨论一些初级的Spring AOP接口,以及在Spring 1.2应用中所使用的AOP支持. 对于新的应用,我们推荐使用 Spring AOP 2.0来支持,在AOP章节有 ...
- Spring 4 官方文档学习 Spring与Java EE技术的集成
本部分覆盖了以下内容: Chapter 28, Remoting and web services using Spring -- 使用Spring进行远程和web服务 Chapter 29, Ent ...
- Spring 通读官方文档
Spring 通读官方文档 这部分参考文档涵盖了Spring Framework绝对不可或缺的所有技术. 其中最重要的是Spring Framework的控制反转(IoC)容器.Spring框架的Io ...
- Google Android官方文档进程与线程(Processes and Threads)翻译
android的多线程在开发中已经有使用过了,想再系统地学习一下,找到了android的官方文档,介绍进程与线程的介绍,试着翻译一下. 原文地址:http://developer.android.co ...
- Spring JMS 官方文档学习
最后部分的XML懒得写了,因为个人更倾向于JavaConfig形式. 为知笔记版本见这里,带格式~ 做了一个小demo,放到码云上了,有兴趣的点我. 说明:需要先了解下JMS的基础知识. 1.介绍 S ...
- Spring Data Commons 官方文档学习
Spring Data Commons 官方文档学习 -by LarryZeal Version 1.12.6.Release, 2017-07-27 为知笔记版本在这里,带格式. Table o ...
- ng的概念层次(官方文档摘录)
官方文档是这么说的: You write Angular applications by: composing HTML templates with Angularized markup, writ ...
- Spring 4 官方文档学习(五)核心技术之SpEL
题外话 官方文档用evaluate这个单词来描述从表达式中获得实际内容的过程.如果直译的话,应该是评估.估值之类的意思.个人以为翻译成解析更易懂,但parse已经是解析了,为了避免冲突,就只好保留了e ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion(二)
接前一篇 Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 本篇主要内容:Spring Type Conver ...
- Spring Framework 官方文档学习(四)之Validation、Data Binding、Type Conversion
本篇太乱,请移步: Spring Framework 官方文档学习(四)之Validation.Data Binding.Type Conversion(一) 写了删删了写,反复几次,对自己的描述很不 ...
随机推荐
- redhat6 yum源配置
第一次接触redhat系统,安装软件时,发现没有ubuntu的apt-get包管理器,自带的yum包管理器又什么都找不到,网上搜了好久,终于把yum配置好了,感谢博主们- 使用redhat系统自带的y ...
- Android事件分发传递
一.与触摸事件有关的几个方法 boolean dispatchTouchEvent(MotionEvent ev); 接收到触摸事件时,是否分发事件到下面的View 返回true:分发触摸事件 返回f ...
- springMVC+spring+hibernate 框架整合实例
先说一下流程思路: 流程讲解1:首先访问会先定位到控制器.这就用到了过滤器配置文件"spring-mvc.xml".这个文件负责定义控制器的包路径.视图的格式等.其次从" ...
- 领域驱动有感<上>
最近看了<领域驱动设计:软件核心复杂性应对之道>,从字面上来看领域驱动就是解决软件复杂性问题的:然而领域驱动设计的门槛很高,没有很深厚的面向对象编码能力几乎不可能实践成功.Martin F ...
- Coping with the TCP TIME-WAIT state on busy Linux servers
Coping with the TCP TIME-WAIT state on busy Linux servers 文章源自于:https://vincent.bernat.im/en/blog/20 ...
- 夜深了,写了个JQuery的省市区三级级联效果
刚刚练手的JQuery,希望大神们指正 主要实现以下功能: 1.三级菜单级联加载数据 2.可以在不操作脚本的情况下,给元素加属性实现级联功能 3.自定义动态显示数据 咨询问题: 对于一般比较固定不变的 ...
- ABP理论学习之数据过滤器
返回总目录 本篇目录 介绍 预定义过滤器 关闭过滤器 开启过滤器 设置过滤器参数 定义自定义过滤器 其他ORM 介绍 软删除模式通常用于不会真正从数据库删除一个实体而是仅仅将它标记为"已删除 ...
- 给Macbook Pro更换固态硬盘并转移系统的最简单办法
没有固态硬盘,再快的CPU,再强悍的显卡,都是白搭,由于“木桶原理”,瓶颈就在这里啊.如今的固态硬盘价格跌了很多,我记得去年我买的120G的固态硬盘还要将近600元,而现在只需要不到400了. 我 ...
- 字符串匹配算法 - KMP
前几日在微博上看到一则微博是说面试的时候让面试者写一个很简单的字符串匹配都写不出来,于是我就自己去试了一把.结果写出来的是一个最简单粗暴的算法.这里重新学习了一下几个经典的字符串匹配算法,写篇文章以巩 ...
- 备忘-Sql server Timeout expired 超时时间已到. 达到了最大池大小 错误及Max Pool Size设置
select * from sysprocesses where dbid= db_id('数据库名') 通过此语句可查看目前所有的连接进程 不够了就必须设置Max Pool Size,理论最大值为3 ...