Reputation: 1657
In my application I have two profiles dev
and prod
, I can exclude beans using org.springframework.context.annotation.Profile
annotation:
package com.example.prod;
@Service
@Profile("prod")
public class MyService implements MyBaseService {}
The problem is, I have several beans which are annotated in such way, all of them are in same package com.example.prod
. Similar structure exists for dev
profile (com.example.dev
package), and may in future I will have some additional profiles. Is there possibility to exclude whole package at once? I tried to play with org.springframework.context.annotation.ComponentScan
, but I was unable to add exclude filters depends on actual profile, I wonder if there is easy way to solve my problem.
Upvotes: 2
Views: 6263
Reputation: 90527
You can implement a custom TypeFilter to disable ComponentScan
for certain packages based on the active profile . A kick-start example is :
(1) Implement the Filter. For demo purpose , I hard codes that if the active profile is dev
, it will exclude the package configured by devExcludePackage
property. For prod
profile , it will exclude the package configured by 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) Configure application.properties
to define which packages to exclude for different profiles.
devExcludePackage = com.example.prod
prodExcludePackage = com.example.dev
(3) Apply this filter to @ComponentScan
:
@SpringBootApplication
@ComponentScan(excludeFilters = @ComponentScan.Filter(
type = FilterType.CUSTOM, classes = { ExcludePackageTypeFilter.class }))
public class Application {
}
Upvotes: 5