標籤:rri service jdbc mvc 技術分享 log over 理解 本質
今天看到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是怎麼做的我就不詳細研究了,哈哈!!!
java 的SPI機制