锁定老帖子 主题:查找项目中实现接口的所有类
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2010-11-16
liquidthinker 写道 楼上,你太打击楼主的动手能力了
无所谓打击不打击了,习惯了. |
|
返回顶楼 | |
发表时间:2010-11-17
最后修改:2010-11-17
将配置文件写在/META-INF/services下,并使用java.util.ServiceLoader去加载。即使以后所有的实现不在同一个jar里也OK,比如java.sql.Driver等接口都是如此实现的。
查很多资料,不如多读一下API和常用jar的源码。国内资料很令人失望。 演示如下 public interface IFunction { //某个接口... } public class IFunctionImpl implements IFunction { //该接口的实现... } public class FooImpl implements IFunction { // 该接口的其他实现... } #filename:META-INF/services/IFunction IFunctionImpl FooImpl import java.util.Iterator; import java.util.ServiceLoader; public class Main { /** * @param args */ public static void main(String[] args) { // 配置文件写在META-INF/services/下,文件名为该接口名,没有文件后缀,一行一个实现,#表示该行为注释。 iterator(java.sql.Driver.class); /* * sun.jdbc.odbc.JdbcOdbcDriver@83cc67 * org.hsqldb.jdbc.JDBCDriver@e09713 */ iterator(IFunction.class); /* * IFunctionImpl@47b480 * FooImpl@10d448 */ } public static <T> void iterator(Class<T> service) { Iterator<T> iterator = ServiceLoader.load(service).iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } } |
|
返回顶楼 | |
发表时间:2010-11-17
undancer 写道 将配置文件写在/META-INF/services下,并使用java.util.ServiceLoader去加载。即使以后所有的实现不在同一个jar里也OK,比如java.sql.Driver等接口都是如此实现的。
查很多资料,不如多读一下API和常用jar的源码。国内资料很令人失望。 演示如下 public interface IFunction { //某个接口... } public class IFunctionImpl implements IFunction { //该接口的实现... } public class FooImpl implements IFunction { // 该接口的其他实现... } #filename:META-INF/services/IFunction IFunctionImpl FooImpl import java.util.Iterator; import java.util.ServiceLoader; public class Main { /** * @param args */ public static void main(String[] args) { // 配置文件写在META-INF/services/下,文件名为该接口名,没有文件后缀,一行一个实现,#表示该行为注释。 iterator(java.sql.Driver.class); /* * sun.jdbc.odbc.JdbcOdbcDriver@83cc67 * org.hsqldb.jdbc.JDBCDriver@e09713 */ iterator(IFunction.class); /* * IFunctionImpl@47b480 * FooImpl@10d448 */ } public static <T> void iterator(Class<T> service) { Iterator<T> iterator = ServiceLoader.load(service).iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } } } 哈哈,/META-INF/services来说也是一个配置, Lz要的是最灵活的方法 以前也有过类似的想法,自动扫描一个指定接口的实现或者指定后缀的名字,扫到class后自动注册到一个Responsiory中。 这样会存在一些问题,比如你要扫描的class的package是一个父级的,比如com.xxxx。在公司这么多lib库下,这时候你遍历整个classpath真的要死人了 |
|
返回顶楼 | |
发表时间:2010-11-17
最后修改:2010-11-17
引用 哈哈,/META-INF/services来说也是一个配置, Lz要的是最灵活的方法
以前也有过类似的想法,自动扫描一个指定接口的实现或者指定后缀的名字,扫到class后自动注册到一个Responsiory中。 这样会存在一些问题,比如你要扫描的class的package是一个父级的,比如com.xxxx。在公司这么多lib库下,这时候你遍历整个classpath真的要死人了 这也是没办法的.为了灵活就必须牺牲一点效率. 反正这东西就在启动时扫描一次,应该可以接受.加载后就缓存吧. |
|
返回顶楼 | |
发表时间:2010-11-17
undancer 写道 将配置文件写在/META-INF/services下,并使用java.util.ServiceLoader去加载。即使以后所有的实现不在同一个jar里也OK,比如java.sql.Driver等接口都是如此实现的。
感谢,又学到一点API. 这位童鞋的话真是精辟啊,我找了google的第一页,做法都一样,很多还是互相转的.都没人试试真的能不能行..... 没办法,只能自己想想解决了. |
|
返回顶楼 | |
发表时间:2010-11-19
设计问题,应该给使用者提供一个方法注入实现类对象,缺省使用你自己的实现类或什么都不做的实现类。
|
|
返回顶楼 | |
发表时间:2010-11-21
一般做项目的话 借口放在一个叫interface包中,实现类放在一个叫impl的包中,这样保证方便
|
|
返回顶楼 | |
发表时间:2010-11-26
你可以参考一下 java.lang.instrument 包的内容。
|
|
返回顶楼 | |
发表时间:2010-11-27
何谓灵活性?通过配置来定制系统不算灵活吗?自动搜索实现类可以做到个性化定制吗?
几个简单的问题: 如果你想替换其中某个函数的实现,怎么做? 如果函数是跟外部资源相关的,那么不同的运行环境需要选择不同的实现,怎么做? 我的建议是:配置必需有,自动搜索、加载的方法可以做,但只限于辅助配置管理的工具。 |
|
返回顶楼 | |
发表时间:2010-11-29
taolei0628 写道 何谓灵活性?通过配置来定制系统不算灵活吗?自动搜索实现类可以做到个性化定制吗?
几个简单的问题: 如果你想替换其中某个函数的实现,怎么做? 如果函数是跟外部资源相关的,那么不同的运行环境需要选择不同的实现,怎么做? 我的建议是:配置必需有,自动搜索、加载的方法可以做,但只限于辅助配置管理的工具。 配置文件自然有的,我自己实现的函数就在配置文件里写的.这些是为不能写入配置文件的人做的.譬如,我的jar经过了签名,别人就不能动我的jar了,也就不能再改我的配置文件里,所以要自动加载.至于替换函数,别人可以写个同名函数.因为是先加载我的,后加载他的,而我定的规则就是后加载的覆盖前加载的,这样就实现了替换. |
|
返回顶楼 | |