和spring cloud/boot 学习如何管理自己的组件
案例,
功能:
需要写一个往kafka上报数据的组建。
当组建启动时,需要建立如下资源:
1, 和kafka建立若干条连接
2, 启动一个线程池
3, 启动上报一个缓冲区
问题如下:
1, 如何在spring工程中引入该组件,并注入到spring容器中
2, 如间接被引用到此JAR包(如 引用的工程有引用到此组建JAR),或只是想用到里面数据类型,并不打算用功能时,如何避免资源会随着引入而自行启动造成资源浪费
3, 组建的配置如何统一管理问题
4, 如何管理众多JAR包依赖,如, 此组建开发要用到kafka的0.11.0.2,有天需要升级到1.0.0
这些问题其实在spring cloud中都有比较好的解决方案,如 zuul, 后面也是仿造zuul的解决
一, 如何使该组建被spring工程引入
SPI方式,
如 zuul 的通过
\META-INF\spring.factories
进行引入 ,指定引导目录
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.cloud.netflix.zuul.ZuulServerAutoConfiguration,\
org.springframework.cloud.netflix.zuul.ZuulProxyAutoConfiguration
故 组建也定义如下
\META-INF\spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zhenai.security.report.SecurityAutoConfiguration
在SecurityAutoConfiguration中,根据需要对bean进行初始化,和相关资源的启动。如 启动连接,启动本地线程池等。
但这里的问题是,只要引入了这个JAR包(包括间接引入该JAR包),那么所有工程都会平白无故的去连kafka,去启动一些无用的线程池
二, 如何屏蔽间接被引用到此JAR包的工程启动相关资源
解决这个问题,spring cloud和spring boot还稍有不同,先看spring cloud.
Marker方式
spring cloud标签模式
先看zuul是怎么做的, 如要在工程里启动ZUUL,一般会在main类里加入@EnableZuulProxy 标签,如下:
@SpringBootApplication
@EnableEurekaClient
@EnableZuulProxy
public class Application {
... ....
}
需要引入@EnableZuulProxy 标签
@EnableZuulProxy的源码如下 : @EnableCircuitBreaker
@EnableDiscoveryClient
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(ZuulProxyMarkerConfiguration.class)
public @interface EnableZuulProxy {
}
看到 @Import(ZuulProxyMarkerConfiguration.class), ZuulProxyMarkerConfiguration只做了一件事,引入一个maker标签
如下:
@Configuration
public class ZuulProxyMarkerConfiguration {
@Bean
public Marker zuulProxyMarkerBean() {
return new Marker();
} class Marker {
}
}
这个Maker对象用作是否启动启用该配置,从而控制了资源是否启动,如 ZuulServerAutoConfiguration
@Configuration
@EnableConfigurationProperties({ ZuulProperties.class })
@ConditionalOnClass(ZuulServlet.class)
@ConditionalOnBean(ZuulServerMarkerConfiguration.Marker.class)
// Make sure to get the ServerProperties from the same place as a normal web app would
@Import(ServerPropertiesAutoConfiguration.class)
public class ZuulServerAutoConfiguration {
... ...
}
根据是否有Marker进行相关类的注入,是否启动。
故:
此处,案例中的组件也选用了这种方式,如
@EnableZASecurityReport 标签
当需要启动时,在main类里加入标签即可,如
@EnableZASecurityReport
public class Application { ... .... }
后续kafka的连接类,线程池,缓冲区等是否分配都可以根据相关标识进行管理,如spi入口类SecurityAutoConfiguration :
@Configuration
@EnableConfigurationProperties({ SecurityReportProperties.class })
@ConditionalOnBean(SecurityProxyMarkerConfiguration.Marker.class)
public class SecurityAutoConfiguration {
... ...
}
这样,如果在main启动类中,只要未加入@EnableZASecurityReport,那么即使引入了组件的JAR包,相关资源也不会被启动。
starter方式
还有一种方式,即,spring boot用的比较多的start方式
spring boot的所有配置都在spring-boot-autoconfigure/META-INF/spring.factories里,通过@ConditionalOnBean特定类是否引入来判断是否启动资源。
如: spring-boot-starter-data-redis
首先通过spring.factories,引入Redis的引导类
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
如:
RedisAutoConfiguration
@Configuration
@ConditionalOnClass({ RedisOperations.class })
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
... ...
}
当工程需要用到Redis时,通过Maven引入相关类
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
</dependency>
spring-boot-starter-data-redis, 其实是一个空项目,有个spring.provides,通过它引入redis相关的JAR包,然后使@ConditionalOnClass生效,从而完成对Redis的JAR环境的初始化。
三, 配置如何统一管理问题
一个组件(JAR包)出来后,配置会比较多,比如该项目涉及到kafka配置,线程池配置等一大堆,传统方式是去写个相关说明文档,一堆配置项会让使用起来很是麻烦。
1, 约定优于配置
在spring cloud/boot中,最让人好用的就是 约定优于配置。记住约定,少写配置
如在zuul中, 只需要配置几个必须项,其它都是约定项
如,约定配置文件即application.yml( 或 bootstrap.yml):
zuul:
debug:
routes:
ZHENAI-CLIENT:
path: /test/**
简单配置下routes就可以启动,如果要找到zuul的配置的约定值,可以直接寻找总配置类ZuulProperties,
ZuulProperties里,包含了所有配置项,并通过配置对象的方式进行模块话的划分如:
ZuulRoute相关,Host相关,HystrixSemaphore相关等
(也是一种默认约定)
故,
在组件中,也可以模仿简化下配置。 此组件核心功能就是上报,比配项目应该只是kafka的地址,要启用,只需要
report.kafkaConfig.servers=X.X.X.X:9092
即可,若要详细配置,和约定值,用一个统一配置文件管 ReportProperties.java
里面注明约定配置的值
2,运用spring的自动装配功能
运用@ConfigurationProperties标签进行自动装配。这个所有基本功能不细说。
详细可查看ZuulProperties里。
好处在于:
1, 可以实现动态配置,如 配置 map,list,甚至enums等
2,如果配合spring cloud config,可以实现动态热更新
四,统一管理JAR包的依赖
参考spring cloud/boot 里,JAR文件统一在spring-boot-dependencies的项目里单独管理,而版本间的兼容,依靠了开源项目http://platform.spring.io/platform/ 来做管理,故很少存在版本冲突。
作为自研的组件,最好依赖到的第三方jar都由spring boot去同理管理版本号,而需要用到的其它jar,可用建立个dependencies项目单独管理起来,不再自己工程能写版本号,方便统一升级维护。
总结下:
1, 如何给spring /spring boot 项目提供组件会比较好
用SPI方式,方便平滑引用
2,如何避免不需要用到组件的项目误引用JAR后,自动启动组件相关资源
1, 提供@EnableXXX标签模式,注入一个marker标签,在启动时通过@ConditionalOnBean来判断
2,starter方式,配置与类分开,@ConditionalOnBean来判断,同时引用时才启动会
3,组件的配置如何统一管理
1, 约定大于配置,简化配置。 为每个组件统一一个组件的XXXProperties.java,并提供约定值
2,自动装配模式
4, 如何统一管理JAR包,防止JAR版本冲突等
交给spring boot统一管理,其它版本号统一在父工程(或加入dependencies工程) 管理版本
加个广告,新的一年,打算把公众号维护起来,质量做起来。
欢迎关注下,谢谢

和spring cloud/boot 学习如何管理自己的组件的更多相关文章
- 《Spring Cloud》学习(一) 服务治理!
前言:之前网上学习过Spring Cloud,对于工作上需要是足够了,总归对于一些方面一知半解,最近难得有些闲暇时间,有幸读了崔永超先生的<Spring Cloud 微服务实战>,一方面记 ...
- spring cloud(学习笔记)高可用注册中心(Eureka)的实现(二)
绪论 前几天我用一种方式实现了spring cloud的高可用,达到两个注册中心,详情见spring cloud(学习笔记)高可用注册中心(Eureka)的实现(一),今天我意外发现,注册中心可以无限 ...
- spring cloud深入学习(四)-----eureka源码解析、ribbon解析、声明式调用feign
基本概念 1.Registe 一一服务注册当eureka Client向Eureka Server注册时,Eureka Client提供自身的元数据,比如IP地址.端口.运行状况指标的Uri.主页地址 ...
- 《Spring Cloud》学习(三) 容错保护!
在微服务架构中,我们将系统拆分成了很多服务单元,各单元的应用间互相依赖.由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身间题出现调用故障或延迟,而 ...
- 《Spring Cloud》学习(二) 负载均衡!
第二章 负载均衡 负载均衡是对系统的高可用.网络压力的缓解和处理能力扩容的重要手段之一.Spring Cloud Ribbon是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于Netfli ...
- 分享spring、spring boot、spring cloud一些学习资源,从基础知识到项目实战
1.spring注解驱动开发,学习spring boot和spring cloud必备知识 链接: https://pan.baidu.com/s/1xhULzLlpkERhoMi1G5Lgfg 密码 ...
- Spring Boot 和 Spring Cloud 应用内存如何管理?
在整体应用架构中,非生产环境情况下,一般 1GB 或者 2GB 的 RAM 就足够了.如果我们将这个应用程序划分为 20 或 30 个独立的微服务,那么很难期望 RAM 仍将保持在 1GB 或 2GB ...
- Spring Cloud Alibaba学习笔记(15) - 整合Spring Cloud Gateway
Spring Cloud Gateway 概述 Spring Cloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基于Netty.Reactor以及WEbFlux构建,它 ...
- Spring Cloud Stream学习(五)入门
前言: 在了解完RabbitMQ后,再来学习SpringCloudStream就轻松很多了,SpringCloudStream现在主要支持两种消息中间件,一个是RabbitMQ,还有一个是KafK ...
随机推荐
- 计蒜客:百度的科学计算器(简单)【python神解】
题目链接:https://nanti.jisuanke.com/t/15504 题解:python大法好啊,三行代码无人能敌啊! 下面给出AC代码: b=input() a=input() print ...
- HDU-5340 Three Palindromes(字符串哈希)
http://acm.hdu.edu.cn/showproblem.php?pid=5340 orz到了新的字符串hash姿势 #include<cstdio>#include<cs ...
- Slim Span(Kruskal)
题目链接:http://poj.org/problem?id=3522 Slim Span Time Limit: 5000MS Memory Limit: 65536K Total Subm ...
- spring boot容器启动详解
目录 一.前言 二.容器启动 三.总结 =======正文分割线====== 一.前言 spring cloud大行其道的当下,如果不了解基本原理那么是很纠结的(看见的都是约定大于配置,但是原理呢?为 ...
- 【学习笔记】Java finalize()的使用
<Java编程思想>中有提到,Java的垃圾回收器并不是那么靠谱,垃圾回收会占用很大的资源开销,垃圾回收器很懒,当变量和对象不再被引用.脱离作用域的时候,垃圾回收器会不定时的进行垃圾回收, ...
- 八大免费SSL证书-给你的网站免费添加Https安全加密
评论» https://www.freehao123.com/top-8-free-ssl-cert/ 文章目录 Let's Encrypt StartSSL SSL CloudFlare SSL ...
- 整理关于web项目如何防止CSRF和XSS攻击的方法
1 了解CSRF的定义 CSRF(Cross-site request forgery)跨站请求伪造,也被称为"One Click Attack"或者Session Riding, ...
- svn冲突文件解决方法
svn冲突文件解决方法 工具/原料 svn客户端 方法/步骤 1 通过SVN客户端更新需要的文件,如果出现有感叹号的文件,找到出现感叹号的文件. 2 选择感叹号文件,即冲突文件,单击鼠标右键对冲突文件 ...
- CCF系列之I’m stuck!(201312-5)
试题名称: I’m stuck! 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一个R行C列的地图,地图的每一个方格可能是'#', '+', '-', '|', '.', ...
- CCF系列之最大的矩形(201312-3)
试题名称: 最大的矩形 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi.这n个矩 ...