论坛首页 Java企业应用论坛

查找项目中实现接口的所有类

浏览 14183 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-11-16  
liquidthinker 写道
楼上,你太打击楼主的动手能力了

无所谓打击不打击了,习惯了.
0 请登录后投票
   发表时间: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());
		}
	}

}

1 请登录后投票
   发表时间: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真的要死人了
0 请登录后投票
   发表时间:2010-11-17   最后修改:2010-11-17
引用
哈哈,/META-INF/services来说也是一个配置, Lz要的是最灵活的方法

以前也有过类似的想法,自动扫描一个指定接口的实现或者指定后缀的名字,扫到class后自动注册到一个Responsiory中。

这样会存在一些问题,比如你要扫描的class的package是一个父级的,比如com.xxxx。在公司这么多lib库下,这时候你遍历整个classpath真的要死人了

这也是没办法的.为了灵活就必须牺牲一点效率.
反正这东西就在启动时扫描一次,应该可以接受.加载后就缓存吧.
0 请登录后投票
   发表时间:2010-11-17  
undancer 写道
将配置文件写在/META-INF/services下,并使用java.util.ServiceLoader去加载。即使以后所有的实现不在同一个jar里也OK,比如java.sql.Driver等接口都是如此实现的。


感谢,又学到一点API.
这位童鞋的话真是精辟啊,我找了google的第一页,做法都一样,很多还是互相转的.都没人试试真的能不能行.....
没办法,只能自己想想解决了.
0 请登录后投票
   发表时间:2010-11-19  
设计问题,应该给使用者提供一个方法注入实现类对象,缺省使用你自己的实现类或什么都不做的实现类。
0 请登录后投票
   发表时间:2010-11-21  
一般做项目的话  借口放在一个叫interface包中,实现类放在一个叫impl的包中,这样保证方便
0 请登录后投票
   发表时间:2010-11-26  
你可以参考一下 java.lang.instrument 包的内容。
0 请登录后投票
   发表时间:2010-11-27  
何谓灵活性?通过配置来定制系统不算灵活吗?自动搜索实现类可以做到个性化定制吗?
几个简单的问题:

    如果你想替换其中某个函数的实现,怎么做?
    如果函数是跟外部资源相关的,那么不同的运行环境需要选择不同的实现,怎么做?

我的建议是:配置必需有,自动搜索、加载的方法可以做,但只限于辅助配置管理的工具。

0 请登录后投票
   发表时间:2010-11-29  
taolei0628 写道
何谓灵活性?通过配置来定制系统不算灵活吗?自动搜索实现类可以做到个性化定制吗?
几个简单的问题:

    如果你想替换其中某个函数的实现,怎么做?
    如果函数是跟外部资源相关的,那么不同的运行环境需要选择不同的实现,怎么做?

我的建议是:配置必需有,自动搜索、加载的方法可以做,但只限于辅助配置管理的工具。


配置文件自然有的,我自己实现的函数就在配置文件里写的.这些是为不能写入配置文件的人做的.譬如,我的jar经过了签名,别人就不能动我的jar了,也就不能再改我的配置文件里,所以要自动加载.至于替换函数,别人可以写个同名函数.因为是先加载我的,后加载他的,而我定的规则就是后加载的覆盖前加载的,这样就实现了替换.
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics