netty源碼註釋有云:java
... If a provider class has been installed in a jar file that is visible to the system class loader, and that jar file contains a provider-configuration file named <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource directory <tt>META-INF/services</tt>, then the first class name specified in that file is taken. The class is loaded and instantiated; if this process fails then an unspecified error is thrown. ...
不知所云?好吧,重點是,jar文件中在META-INF/services
目錄下配置了A屬性,以某種方式能加載到。maven
how can do that? 答曰:ServiceLoaderide
ServiceLoader
直譯爲服務加載器
,最終目的是獲取service的impl實現類。正如前文所說,它將加載META-INF/services
下的配置文件,來鎖定impl實現類。this
1.首先,要有一個接口netty
//形狀接口 public interface Shape { String introduce(); //介紹 }
2.而後,要有該接口的實現類。實現類很簡單,介紹本身的形狀是啥code
//實現類一 public class Circle implements Shape { public String introduce() { return "圓形"; //言簡意賅的介紹 } }
//實現類二 public class Sequare implements Shape { static{ System.out.println("【Sequare】聽說有延時加載,try it.."); } public String introduce() { return "方形"; } }
眼尖的朋友可能已經注意到了,這裏有個靜態塊,由於資料中有提到ServiceLoader有延時加載的效果。寡人不信,遂驗之……接口
3.配置文件,放在META-INF/services
ci
文件位置:源碼
- src -main -resources - META-INF - services - xxxpackage.Shape
文件名:包名.接口名it
文件內容:包名.接口實現類,換行符分隔
xxxpackage.Circle xxxpackage.Sequare
4.ServiceLoader調用
ServiceLoader<Shape> shapeLoader = ServiceLoader.load(Shape.class); Iterator<Shape> it = shapeLoader.iterator(); while(it.hasNext()){ System.out.println("Iterator<Shape> next()方法調用.."); Shape shape = it.next(); System.out.printf("what's shape?%s\n",shape.introduce()); }
調用結果:
Iterator<Shape> next()方法調用.. 【Sequare】聽說有延時加載,try it.. what's shape?方形
從該結果可看出,在調用it.next()
的時候,才真正的加載了Sequare
類,確確實實是延時加載。期具體實現依靠ServiceLoader的內部類LazyIterator,感性趣的朋友能夠本身看一下。