如何在 Spring 引导应用程序中排除给定运行时配置文件中的包
How to exclude package in given runtime profile in Spring Boot application
在我的应用程序中,我有两个配置文件 dev
和 prod
,我可以使用 org.springframework.context.annotation.Profile
注释排除 bean:
package com.example.prod;
@Service
@Profile("prod")
public class MyService implements MyBaseService {}
问题是,我有几个以这种方式注释的 bean,它们都在同一个包中 com.example.prod
。 dev
配置文件(com.example.dev
包)存在类似的结构,将来我可能会有一些额外的配置文件。是否有可能一次排除整个包裹?我尝试玩 org.springframework.context.annotation.ComponentScan
,但我无法添加排除过滤器,具体取决于实际配置文件,我想知道是否有简单的方法可以解决我的问题。
您可以实施自定义 TypeFilter 以根据活动配置文件禁用某些软件包的 ComponentScan
。启动示例是:
(1) 实施过滤器。出于演示目的,我硬编码如果活动配置文件是 dev
,它将排除由 devExcludePackage
属性 配置的包。对于 prod
配置文件,它将排除由 prodExcludePackage
配置的包:
public class ExcludePackageTypeFilter implements TypeFilter , EnvironmentAware {
private Environment env;
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
boolean match = false;
for (String activeProfile : env.getActiveProfiles()) {
if (activeProfile.equals("dev")) {
match = isClassInPackage(metadataReader.getClassMetadata(), env.getProperty("devExcludePackage"));
} else if (activeProfile.equals("prod")) {
match = isClassInPackage(metadataReader.getClassMetadata(), env.getProperty("prodExcludePackage"));
}
}
return match;
}
private boolean isClassInPackage(ClassMetadata classMetadata, String pacakage) {
return classMetadata.getClassName().startsWith(pacakage);
}
@Override
public void setEnvironment(Environment environment) {
this.env = environment;
}
}
(2) 配置 application.properties
以定义为不同的配置文件排除哪些包。
devExcludePackage = com.example.prod
prodExcludePackage = com.example.dev
(3) 将此过滤器应用于 @ComponentScan
:
@SpringBootApplication
@ComponentScan(excludeFilters = @ComponentScan.Filter(
type = FilterType.CUSTOM, classes = { ExcludePackageTypeFilter.class }))
public class Application {
}
在我的应用程序中,我有两个配置文件 dev
和 prod
,我可以使用 org.springframework.context.annotation.Profile
注释排除 bean:
package com.example.prod;
@Service
@Profile("prod")
public class MyService implements MyBaseService {}
问题是,我有几个以这种方式注释的 bean,它们都在同一个包中 com.example.prod
。 dev
配置文件(com.example.dev
包)存在类似的结构,将来我可能会有一些额外的配置文件。是否有可能一次排除整个包裹?我尝试玩 org.springframework.context.annotation.ComponentScan
,但我无法添加排除过滤器,具体取决于实际配置文件,我想知道是否有简单的方法可以解决我的问题。
您可以实施自定义 TypeFilter 以根据活动配置文件禁用某些软件包的 ComponentScan
。启动示例是:
(1) 实施过滤器。出于演示目的,我硬编码如果活动配置文件是 dev
,它将排除由 devExcludePackage
属性 配置的包。对于 prod
配置文件,它将排除由 prodExcludePackage
配置的包:
public class ExcludePackageTypeFilter implements TypeFilter , EnvironmentAware {
private Environment env;
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
boolean match = false;
for (String activeProfile : env.getActiveProfiles()) {
if (activeProfile.equals("dev")) {
match = isClassInPackage(metadataReader.getClassMetadata(), env.getProperty("devExcludePackage"));
} else if (activeProfile.equals("prod")) {
match = isClassInPackage(metadataReader.getClassMetadata(), env.getProperty("prodExcludePackage"));
}
}
return match;
}
private boolean isClassInPackage(ClassMetadata classMetadata, String pacakage) {
return classMetadata.getClassName().startsWith(pacakage);
}
@Override
public void setEnvironment(Environment environment) {
this.env = environment;
}
}
(2) 配置 application.properties
以定义为不同的配置文件排除哪些包。
devExcludePackage = com.example.prod
prodExcludePackage = com.example.dev
(3) 将此过滤器应用于 @ComponentScan
:
@SpringBootApplication
@ComponentScan(excludeFilters = @ComponentScan.Filter(
type = FilterType.CUSTOM, classes = { ExcludePackageTypeFilter.class }))
public class Application {
}