功能需求

  1. 提供一个公共的jar包给其他业务模块依赖,需要在这个公共的jar中暴露一个restful API

  2. 采用spring auto config机制,在公共jar包中定义spring.factories文件,将jar包需要注入到spring容器中的bean定义好,业务模块依赖后直接使用,不需要额外定义bean,也不需要指定ComponentScan

之前做法:根据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;
}
}
}
}

发现这个地方查找是否有指定注解时,如果继承的类或实现的接口有相应的注解也是可以的,利用这个特性,我们可以采用如下思路来实现。

  1. 定义一个标记Controller,里面什么方法也没有,仅仅追加了一个注解

    @RestController
    public class MarkController { }
  2. 定义具体的Controller继承这个标记类,注意这个类不需要用RestController注解

public class HelloController extends MarkController {

	@RequestMapping("/hello")
public String hello() {
return "hello";
}

}


3. 在一个Configuration类中用@Bean注解声明这个类 ```
@Configuration
public class BeanConfig { @Bean
public HelloController helloController() {
return new HelloController();
} } ``` 这样我们就可以通过@Bean的形式声明Controller,之后把这个BeanConfig直接追加到spring.factories中,其他模块依赖这个jar之后,自动就会有一个/hello的接口了。

spring boot通过@Bean注解定义一个Controller的更多相关文章

  1. Spring Boot 二十个注解

    Spring Boot 二十个注解 占据无力拥有的东西是一种悲哀. Cold on the outside passionate on the insede. 背景:Spring Boot 注解的强大 ...

  2. spring boot 中@Autowired注解无法自动注入的错误

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/huihuilovei/article/de ...

  3. Spring Boot中@Scheduled注解的使用方法

    Spring Boot中@Scheduled注解的使用方法 一.定时任务注解为@Scheduled,使用方式举例如下 //定义一个按时间执行的定时任务,在每天16:00执行一次. @Scheduled ...

  4. spring boot @ConditionalOnxxx相关注解总结

    Spring boot @ConditionalOnxxx相关注解总结 下面来介绍如何使用@Condition public class TestCondition implements Condit ...

  5. Spring boot 使用的注解有哪些?

    Spring boot 使用的注解有哪些? 注解 作用 @SpringBootApplication 等价于 @Configuration + @EnableAutoConfiguration + @ ...

  6. (32)Spring Boot使用@SpringBootApplication注解,从零开始学Spring Boot

    [来也匆匆,去也匆匆,在此留下您的脚印吧,转发点赞评论] 如果看了我之前的文章,这个节你就可以忽略了,这个是针对一些刚入门的选手存在的困惑进行写的一篇文章. 很多Spring Boot开发者总是使用 ...

  7. Spring Boot 计划任务中的一个“坑”

    计划任务功能在应用程序及其常见,使用Spring Boot的@Scheduled 注解可以很方便的定义一个计划任务.然而在实际开发过程当中还应该注意它的计划任务默认是放在容量为1个线程的线程池中执行, ...

  8. spring boot开发,jar包一个一个来启动太麻烦了,写一个bat文件一键启动

    spring boot开发,jar包一个一个来启动太麻烦了,写一个bat文件一键启动 @echo offcd D:\workProject\bushustart cmd /c "title ...

  9. Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的?

    启动类上面的注解是@SpringBootApplication,它也是 Spring Boot 的核心注解,主要组合包含了以下 3 个注解: @SpringBootConfiguration:组合了 ...

随机推荐

  1. python起个简单web服务器

    在 Linux 服务器上或安装了 Python 的机器上,Python自带了一个WEB服务器 SimpleHTTPServer. 我们可以很简单的使用  python -m SimpleHTTPSer ...

  2. 反思K-S指标(KPMG大数据挖掘)

    评估信用评级模型,反思K-S指标 2015-12-05 KPMG大数据团队 KPMG大数据挖掘 “信用评级”的概念听起来可以十分直截了当.比如一天早上你接到电话,有个熟人跟你借钱,而你将在半睡半醒间迅 ...

  3. CodeForces 825G"Tree Queries"(选根建树)

    传送门 •参考资料 [1]:CodeForces 825G Educational Round #25 G :建树选根大法+O1大法+iostream解绑了还是慢 •题意 给定一颗包含 n 个节点的树 ...

  4. [转]Springboot和SpringMVC区别

    spring boot只是一个配置工具,整合工具,辅助工具. springmvc是框架,项目中实际运行的代码 Spring 框架就像一个家族,有众多衍生产品例如 boot.security.jpa等等 ...

  5. JavaScript:4个常见的内存泄露

    什么是内存泄漏 内存泄漏基本上就是不再被应用需要的内存,由于某种原因,没有被归还给操作系统或者进入可用内存池. 编程语言喜欢不同的管理内存方式.然而,一段确定的内存是否被使用是一个不可判断的问题.换句 ...

  6. win10系统激活 快捷方式

    系统不定期就会提示激活,每次激活都是找各种工具折腾,今天捣鼓简单的脚本直接激活~~ 首先查看自己系统的版本,后面才能找到合适的激活码 win+R 启动程序 输入 winver 即可查看系统版本 2.查 ...

  7. AWS Credentials 使用

    AWS的文档系统真是烂到家了!!!!! To connect to any of the supported services with the AWS SDK for Java, you must ...

  8. H3C 迭代查询

  9. 深入理解Jvm--Java静态分配和动态分配完全解析

    jvm中分配Dispatch的概念 分派是针对方法而言的,指的是方法确定的过程,通常发生在方法调用的过程中.分派根据方法选择的发生时机可以分为静态分派和动态分派,其中对于动态分派,根据宗量种数又可以分 ...

  10. Git用在公司项目上的操作

    修改代码后再次提交 搭档优化好他自己的代码后,我想在vscode上看看他优化后的结果 此时直接git pull origin就可以看到了 j接下来的一些指令,慢慢了解... 分支本身已经在我上面 以下 ...