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,感性趣的朋友能够本身看一下。