java 的SPI機制


今天看到spring mvc 使用Java Validation Api(JSR-303)進行校驗,需要加載一個 其具體實現(比如Hibernate Validator), 本來沒有什么問題,但是突然想到這其中到底是怎樣一種加載過程呢,也就是說spring為什么能夠找到Hibernate Validator來作為JSR-303的具體實現的呢?

1. java中的SPI機制

這篇文章對java的SPI機制講的比較容易理解,就不多做記錄. http://www.cnblogs.com/javaee6/p/3714719.html 

下面的小例子,分別采用SPI機制和 反射類名的方式來獲取服務(helloApi)

首先給出服務接口,將它導出為一個jar包, hello-api.jar

package helloApi;

public interface Hello {
    String say();
}

下面是它的一個具體實現:

package helloImpl;

import helloApi.Hello;

public class HelloImpl implements Hello {
    @Override
    public String say() {
        return "hello Massclouds";
    }
}

將這個實現導出為jar包,但是為了使用java 的SPI機制,我們需要在導出的jar包的META-INF中增加services文件夾,並在其中增加一個文件,以 所實現接口 helloApi.Hello 為名,以 具體實現類 helloImpl.HelloImpl為內容。

最后就是分別使用SPI和反射的方式來獲得服務。

        Hello hello = null;
        //使用java的SPI機制加載Hello api的實現類
        ServiceLoader<Hello> serviceLoader = ServiceLoader.load(Hello.class);
        Iterator<Hello> iter = serviceLoader.iterator();
        if(iter.hasNext()){
            hello = iter.next();
        }
        
        System.out.println(hello.say()); 
        
        //通過反射類名的方式來獲得Hello api的實現
        hello = (Hello)Class.forName("helloImpl.HelloImpl").newInstance();
        System.out.println(hello.say());

回過頭來考慮jdbc的加載方式,跟我上面的例子是一樣的。這兩種方式肯定是SPI更好,采用類名反射的方式本質上還是硬編碼嘛!

2. 如何加載Hibernate Validator來作為JSR-303的實現

我們打開Hibernate Validator的jar包來看看。

而這個文件的內容正是具體實現 org.hibernate.validator.HibernateValidator。至於具體Spring是怎么做的我就不詳細研究了,哈哈!!!

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM