如何使用springboot,整合自定义组件,完成可插拔的效果呢?
原理
使用过springboot的小伙伴们,一定知道springboot整合了好多的功能,如dubbo、webMVC等,其声明了相应的注解类
@EnableDubbo、@EnableWebMvc来作为此组件的开关。
其实现原理也很简单,springboot模拟了Java的spi机制,实现了自己的spi机制,以达到组件之间的解耦效果。第三方只需要在组件资源的根目录下添加META-INF文件夹,在META-INF文件夹下面添加名为spring.factories的文件,并将组件的入口类的全限定类名加入文件中,springboot启动时即可加载。org.springframework.core.io.support.SpringFactoriesLoader#loadFactories完成了加载的工作,属性FACTORIES_RESOURCE_LOCATION指定了加载的路径"META-INF/spring.factories"。
整合自定义的组件,到springboot项目中
笔者这里创建了一个简单的MVC项目,开发了一个接口/buge/mvp,并返回一个“你很帅!”的字符串的这样一个简单的组件。
项目结构:
同时在项目的根目录中创建META-INF/spring.factories文件,并加入org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.buge.dubboapi.starter.Config的配置信息。
重点看下Config类,此类即为组件的配置类:
注意@ConditionalOnBean:当spring容器中含有Buge这个bean时,才会加载Config,可作为组件的一个开关使用;
那何时去生成Buge的bean呢?这需要借助于spring的@Impor注解,来注入自定义的类,交由spring来管理。
项目中@EnableBuge注解,即完成了注入buge的工作。下图可看到,在注解类上添加了@Import(Buge.class)
这里做个小总结:@EnableBuge注解即为我们组件的开关,若添加了此注解,会促使spring加载Buge到spring容器中,而springboot通过spi机制加载的Config类是需要容器中有Buge,所以添加了@EnableBuge注解,Config会生效,组件的功能才可用。当然,把Config类上的 @ConditionalOnBean 去掉后,就没这个bean的限制了。但笔者认为,这个开关还是有必要的!
测试
将以上组件打包,放入本地maven仓库中。创建一个springboot项目,导入组件的依赖。在springboot的启动类上加入@EnableBuge注解。
启动服务,调用组件接口,看结果:
是的,我们开发的组件生效了!倘若想关闭组件的功能,把启动类上的@EnableBuge去掉即可,如下图。继续测试一波:
启动服务,调用组件接口,看结果:
返回404,组件功能关闭!
到此为止,我们就完成了自定义组件,就整合到了springboot中。
思考