在 Spring Boot 应用程序中,如何使用返回类型注释作为过滤器来扫描方法返回类型和注释值?
尝试扫描使用自定义注释进行注释的返回类型对象,但 ClassPathScanningCandidateComponentProvider 找不到它们,即使包是正确的并且元数据显示使用它们注释的方法。
我已向现有的 ClassPathScanningCandidateComponentProvider 添加了一个过滤器,以包含使用自定义注释注释的方法的返回类型,即
@Procedure(name="PROC_MAPPING_NAME")
@CursorList(cursorType=CursorObject.class)CursorHolder<CursorObject> getCursor(@Param("col_1") @NonNull String param);
像这样添加过滤器
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
//existing filters
....
//new filter
scanner.addIncludeFilter(new AnnotationTypeFilter(CursorList.class));
//scan packages
return Arrays.stream(packages)
.map(scanner::findCandidateComponents)
.flatMap(Collection::stream)
.map(BeanDefinition::getBeanClassName)
.map(name -> {
try {
return Class.forName(name);
}
catch (ClassNotFoundException e) {
//handle exception
}
}).collect(Collectors.toList());
适用于所有现有过滤器,并且使用新注释的包肯定包含在内,因为我'已经进入代码了。它只是不符合被视为匹配并返回的标准。
我还在类级别测试了这个注释,然后发现它没有问题。但是,它似乎不适用于属性级别或方法或参数级别。
给出类名如此愚蠢的问题。当注释包含在类级别时,ClassPathScanningCandidateComponentProvider 是否仅适合扫描注释使用情况?即只找到带注释的组件?
如果是这种情况,有没有人对查找注释以及它们注释的对象(其中对象是返回类型)有任何建议?或者这是不可能的?
谢谢
trying to scan for return type objects that are annoated with a custom annoation but the ClassPathScanningCandidateComponentProvider does not find them even though package is correct and metadata shows the methods annoated with them.
I've added a filter to my existing ClassPathScanningCandidateComponentProvider to include return types on methods annotated with a custom annoation, i.e.
@Procedure(name="PROC_MAPPING_NAME")
@CursorList(cursorType=CursorObject.class)CursorHolder<CursorObject> getCursor(@Param("col_1") @NonNull String param);
Filter is added like so
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
//existing filters
....
//new filter
scanner.addIncludeFilter(new AnnotationTypeFilter(CursorList.class));
//scan packages
return Arrays.stream(packages)
.map(scanner::findCandidateComponents)
.flatMap(Collection::stream)
.map(BeanDefinition::getBeanClassName)
.map(name -> {
try {
return Class.forName(name);
}
catch (ClassNotFoundException e) {
//handle exception
}
}).collect(Collectors.toList());
Works fine for all the existing filters and the package where the new annotation is used is definitely included as I've stepped into the code. It just fails to meet the criteria required to be considered a match and returned.
I've also tested this annotation at class level and it is then found without issue. But, it does not seem to work at attribute level or method or param level.
So stupid question given the class name. Is the ClassPathScanningCandidateComponentProvider only suitable for scanning for annoation usage when the annotation is included at class level? i.e. only finds annoated components?
If that is the case has anyone any suggestions for finding annotations and the objects they annoate where the object is a return type? Or is this just not possible?
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
据我调查,
AnnotationTypeFilter
似乎仅匹配类 javadoc 和 实施。幸运的是,我们可以自定义
AnnotationTypeFilter
以使其匹配方法。下面是一个例子。
我们的
CustomAnnotationTypeFilter
匹配这样的类:NOTE
在前面声明带有注释的方法意味着用以下方式注释方法(而不是返回类型)注释。
上面的示例意味着您使用
Procedure
和CursorList
注释getCursor
方法。在这种情况下,您需要在创建自定义过滤器时检查方法是否具有注释。EDIT_1 (2022/3/16)
我考虑到下面的评论添加了一些示例。以下
CustomAnnotationTypeFilter
匹配Baz
、Foo
、Fuga
和Hoge
。扫描组件以查找注释是一个复杂的问题。它不等同于/类似于使用 grep 命令进行搜索。
您必须明确指定目标注释的放置位置。例如,如果方法可以使用注释进行注释,则必须显式检查方法,如
AnnotationUtils.findAnnotation(method, this.getAnnotationType())
(如上面的示例所示)。此外,在某些情况下,您可能必须检查返回类型,如上面的示例。在搜索注释时,使用 org.springframework.core.annotation.AnnotationUtils 等实用程序类会很有帮助。因为此类实用程序的某些方法可以找到
注释,即使它们没有直接出现在给定目标本身上(另请参阅其 javadoc)。
It seems that
AnnotationTypeFilter
matches only classes as far as I investigated its javadoc and implementation.Fortunately, we can customize
AnnotationTypeFilter
in order to make it match methods.The following is an example.
Our
CustomAnnotationTypeFilter
matches a class like:NOTE
Declaring a method with annotations in front of it means to annotate the method (not the return type) with the annotations.
The example above means that you annotate
getCursor
method withProcedure
andCursorList
. In such cases, you need to check whether methods have an annotation when you create a custom filter.EDIT_1 (2022/3/16)
I added some examples considering the comments below. The following
CustomAnnotationTypeFilter
matchesBaz
,Foo
,Fuga
andHoge
.Scanning components to find annotations is a complex problem. It is not equivalent to / similar to searching with grep command.
You have to explicitly specify the location that the target annotation is placed on. For example, if methods can be annotated with the annotation, you have to check methods explicitly like
AnnotationUtils.findAnnotation(method, this.getAnnotationType())
(as the example above shows). Also you may have to check the return types like the example above in a certain situation.It is helpful to use the utility classes like
org.springframework.core.annotation.AnnotationUtils
when searching for annotations. Because some methods of such utilities can findannotations even when they are not directly present on the given target itself(See also its javadoc).