Scan package
很多时候,需要动态的检查某个package下是否包含特定的类,比如继承了某个接口,或是附加上了某个annotation。
这是个典型的听上去容易,做起来麻烦的任务。
如果package的classpath属于
但是如果package位于某一个jar文件中则需要遍历jar file中对应的每一个jar entry。
庆幸的是,始终可以在open source社区中找到"先人"的贡献。
如果你使用Spring (v 2+),一定会对Spring中新增的annotation wire印象深刻,其中包括一个自动在某个package下寻找符合条件的bean的功能。
这个package scanning的功能由
Scanner依赖一个
一旦scan结束,找到的类定义(
这是个典型的听上去容易,做起来麻烦的任务。
如果package的classpath属于
file://
一类,可以直接使用Class.getResourceAsStream("your/package")
打开一个text stream, 其中的每一行为package包含的每一个元素。
import scala.io.{Source}
for(
line <- Source.fromInputStream(aClass.getResourceAsStream("your/package")).getLines
name = line.trim
if match(name)
}yield{
Class.forName(name)
}
但是如果package位于某一个jar文件中则需要遍历jar file中对应的每一个jar entry。
庆幸的是,始终可以在open source社区中找到"先人"的贡献。
如果你使用Spring (v 2+),一定会对Spring中新增的annotation wire印象深刻,其中包括一个自动在某个package下寻找符合条件的bean的功能。
这个package scanning的功能由
org.springframework.context.annotation.ClassPathBeanDefinitionScanner
这个类来完成。默认的设定是找出指定package下带有@Component
的类。不过由于Spring良好的结构,很容易进行扩展。
val reg = new SimpleBeanDefinitionRegistry
val scanner = new ClassPathBeanDefinitionScanner(reg, false)
scanner.setIncludeAnnotationConfig(false)
scanner.addIncludeFilter(new AssignableTypeFilter(classOf[Object]))
scanner.scan("your.pkg")
Scanner依赖一个
TypeFilter
来选择感兴趣的类。在上面的代码中禁止了预先设置的filter,并且用一个AssignableTypeFilter
来代替,因此选择所有的类。一旦scan结束,找到的类定义(
BeanDefinition
)会被放入BeanDefinitionRegistry
这样一个结构中。上面的代码中,使用了SimpleBeanDefinitionRegistry
这样一个简单的实现。
0 comments:
Post a Comment