一.背景
因为Springboot项目是一款标准产品,在ToB部署的时候可能不需要将整个springboot的服务启动起来,而且很多情况下,我们启动整个服务会占用很大的内存,因此迎来一个问题,怎么让springboot只启动一部分的service,而让没有应用到的service、controller不启动。
二.解决方案
1.众所周知,@ComponentScan是用来标注springboot启动扫描的组建,我们只需要在该注解的方法体里面,使用excludeFilters参数来对包下的类进行过滤即可,这里我们使用@Filter注解来对类名进行筛选,FilterType.CUSTOM 表示我们将自己实现一个过滤类来实现类的过滤
在启动类增加@ConponentScan注解
@ComponentScan(basePackages = {"com.cherry"},excludeFilters = {
@Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
})
public class Application{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2.实现自定义过滤类MyTypeFilter,需要实现TypeFilter类,实现里面的match方法
public class MyTypeFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
String className = metadataReader.getClassMetadata().getClassName();
if (className.equals("com.cherry.TestCase")) {
return true;//符合的会被过滤
}
return false;
}
}
三.附:配置方式配置server启动数量
这个时候问题来了,我这个com.cherry.TestCase我不想写死,我想从配置文件里面读,这下就有新的问题了,springboot本身通过组件去获取配置文件的内容需要在springboot启动后才能获取到数据,但是@ComponentScan本身就是在Springboot的启动过程中,这个时候直接用Springboot去读配置文件肯定是拿不到数据的(可以自己试试),这个时候就要另辟蹊径了。
解决方法:引入yml配置文件,用来加载yml配置文件的内容
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.29</version>
</dependency>
加载方式,通过System.serProperty()在Springboot启动的时候,把配置文件的路径传进来
@ComponentScan(basePackages = {"com.cherry"},excludeFilters = {
@Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
})
public class Application{
public static void main(String[] args){
if(args != null && args.length>0) {
System.setProperty("serverPath", args[0]);
}
SpringApplication.run(Application.class, args);
}
}
然后就可以在过滤类中使用,这里我们通过文件流的方式来读取yml文件的数据,因为文件流的操作不是springboot框架的一部分,因此它不需要等待springboot启动就可以将我们配置文件中的数据加载进来。
定义方法如下
public static void setMapProperty() throws IOException {
Yaml yml = new Yaml();
FileReader reader = new FileReader(new File(System.getProperty("serverPath")));
BufferedReader buffer = new BufferedReader(reader);
Map<String,Object> map = yml.load(buffer);
}
所得Map即为配置文件的内容,可以打印出来看看,然后进行引用即可,如何引用这里就不贴出来了。
附上yml文件的配置方式,这里用数据等方式定义要启动的服务,之后引用用map.get(“stopServers”)可以获取到数据信息:
stopServers:
- AudienceController
- AudienceService
# - TagController
# - TagService
- PortraitController
- PortraitService
- EventAnalyzeController
- EventAnalyzeService