opengoofy/crane4j

`@ContainerEnumScan` 注解无法支持带有通配符的路径

Closed this issue · 1 comments

@ContainerEnumScan 注解无法支持带有通配符的路径,现在有如下路径:

  • com.example.core.enums
  • com.example.api.enums

则通过 com.example.**com.example.**.enumscom.example.**.*.enums 均无法扫描到对应的枚举。

@ContainerConstantScan@OperatorScan 似乎也是这个情况。

这个问题似乎是底层使用的 PathMatchingResourcePatternResolver 造成的,参见这一段注释:

WARNING: Ant-style patterns with "classpath:" resources are not guaranteed to find matching resources if the root package to search is available in multiple class path locations. This is because a resource such as

  com/mycompany/package1/service-context.xml

may be in only one location, but when a path such as

  classpath:com/mycompany/**/service-context.xml

is used to try to resolve it, the resolver will work off the (first) URL returned by getResource("com/mycompany");. If this base package node exists in multiple classloader locations, the actual end resource may not be underneath. Therefore, preferably, use "classpath*:" with the same Ant-style pattern in such a case, which will search all class path locations that contain the root package.

从字面上理解,如果我们使用 classpath:com/example/package 或者 com/example/package —— 默认情况下两者是等价的 —— 去从项目的根路径开始扫描时,如果引入了多个依赖中存在相同的包路径,那么仅会加载首个匹配的路径下的类。

举个例子,假如项目中引入了 A 和 B 两个依赖,它们的目录结构分别是 com/example/package/acom/example/package/b,此时,由于我们指定扫描的路径是 com/example/package,当匹配到 com/example/package/a 时就会认为已经找到了,后面就不会再扫描 com/example/package/b 路径了。

这个问题通过在扫描路径前端添加 classpath*/ 即可解决。