spring boot通过@Bean注解定义一个Controller,
分享于 点击 10728 次 点评:13
spring boot通过@Bean注解定义一个Controller,
功能需求
之前做法:根据spring文档给的方案调用RequestMappingHandlerMapping的registerMapping方法手动注册一个mapping,可以不使用@Controller注解就可以追加一个rest 接口,可是spring 5之后,spring推出了spring web flux,而RequestMappingHandlerMapping也分成了是spring webmvc版和spring webflux两个,我们给定的jar又不能限定业务模块使用spring web还是spring web flux开发,所以这种方式就不适用了。
解决方式
我们知道,无论是webmvc还是webflux中的RequestMappingHandlerMapping类,都是在afterPropertiesSet方法中查找所有带有Controller或者RequestMapping注解的类,再把对应类中的带有RequestMapping注解的方法解析后注册到对应的RequestMappingHandlerMapping中的,其中判断一个类是否带有@Controller或@RequestMapping的方法如下
@Override
protected boolean isHandler(Class<?> beanType) {
return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class) ||
AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class));
}
对应的AnnotatedElementUtils.hasAnnotation方法,最终会调用到AnnotatedElementUtils.searchWithFindSemantics方法,代码片段如下
else if (element instanceof Class) {
Class<?> clazz = (Class<?>) element;
if (!Annotation.class.isAssignableFrom(clazz)) {
// Search on interfaces 在实现接口中查找
for (Class<?> ifc : clazz.getInterfaces()) {
T result = searchWithFindSemantics(ifc, annotationTypes, annotationName,
containerType, processor, visited, metaDepth);
if (result != null) {
return result;
}
}
// Search on superclass 在父类中查找
Class<?> superclass = clazz.getSuperclass();
if (superclass != null && superclass != Object.class) {
T result = searchWithFindSemantics(superclass, annotationTypes, annotationName,
containerType, processor, visited, metaDepth);
if (result != null) {
return result;
}
}
}
}
发现这个地方查找是否有指定注解时,如果继承的类或实现的接口有相应的注解也是可以的,利用这个特性,我们可以采用如下思路来实现。
相关文章
- 暂无相关文章
用户点评