首页 > PHP资讯 > JAVA培训 > 你不知道的5个Java有用的工具(2)

你不知道的5个Java有用的工具(2)

JAVA培训

2. ServiceLoader

Java 开发人员经常希望将使用和创建组件的内容区分开来。这通常是通过创建一个描述组件动作的接口,并使用某种中介创建组件实例来完成的。很多开发人员使用 Spring 框架来完成,但还有其他的方法,它比 Spring 容器更轻量级。

java.util 的 ServiceLoader 类能读取隐藏在 JAR 文件中的配置文件,并找到接口的实现,然后使这些实现成为可选择的列表。例如,如果您需要一个私仆(personal-servant)组件来完成任务,您可以使用清单 2 中的代码来实现:

清单 2. IPersonalServant


      
public interface IPersonalServant  
{  
    // Process a file of commands to the servant  
    public void process(java.io.File f)  
        throws java.io.IOException;  
    public boolean can(String command);  
}  

can() 方法可让您确定所提供的私仆实现是否满足需求。清单 3 中的 ServiceLoader 的 IPersonalServant 列表基本上满足需求:

清单 3. IPersonalServant 行吗?


      
import java.io.*;  
import java.util.*;  

public class Servant  
{  
    public static void main(String[] args)  
        throws IOException  
    {  
        ServiceLoader<IPersonalServant> servantLoader =   
            ServiceLoader.load(IPersonalServant.class);  

        IPersonalServant i = null;  
        for (IPersonalServant ii : servantLoader)  
            if (ii.can("fetch tea"))  
                i = ii;  

        if (i == null)  
            throw new IllegalArgumentException("No suitable servant found");  
          
        for (String arg : args)  
        {  
            i.process(new File(arg));  
        }  
    }  
}  

假设有此接口的实现,如清单 4:

清单 4. Jeeves 实现了 IPersonalServant


import java.io.*;  

public class Jeeves  
    implements IPersonalServant  
{  
    public void process(File f)  
    {  
        System.out.println("Very good, sir.");  
    }  
    public boolean can(String cmd)  
    {  
        if (cmd.equals("fetch tea"))  
            return true;  
        else  
            return false;  
    }  
}  

剩下的就是配置包含实现的 JAR 文件,让 ServiceLoader 能识别 — 这可能会非常棘手。JDK 想要 JAR 文件有一个 META-INF/services 目录,它包含一个文本文件,其文件名与接口类名完全匹配 — 本例中是 META-INF/services/IPersonalServant。接口类名的内容是实现的名称,每行一个,如清单 5:

清单 5. META-INF/services/IPersonalServant


      
Jeeves   # comments are OK  

幸运的是,Ant 构建系统(自 1.7.0 以来)包含一个对 jar 任务的服务标签,让这相对容易,见清单 6:

清单 6. Ant 构建的 IPersonalServant



<target name="serviceloader" depends="build"> 
    <jar destfile="misc.jar" basedir="./classes"> 
        <service type="IPersonalServant"> 
            <provider classname="Jeeves" /> 
        </service> 
    </jar> 
</target> 

这里,很容易调用 IPersonalServant,让它执行命令。然而,解析和执行这些命令可能会非常棘手。这又是另一个 “小线头”。

常州java培训

本文由欣才IT学院整理发布,未经许可,禁止转载。