Solution 1: Spring Method
The simplest answer is to keep track of how Spring subprojects (boot, data ...) implement this type of requirement. Usually they define a custom annotation that allows you to use this feature and define a set of packages for scanning.
For example, given this annotation:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Import({MyInterfaceScanRegistrar.class}) public @interface MyInterfaceScan { String[] value() default {}; }
Where value determines the packets to scan, and @Import enables MyInterfaceScan detection.
Then create an ImportBeanDefinitionRegistrar . This class will be able to create a bean definition.
An interface to be implemented by types that register additional bean definitions when processing @Configuration classes. Useful when working at the bean definition level (as opposed to the @ Bean method / instance level) is desired or necessary.
public class MyInterfaceScanRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware { private Environment environment; @Override public void setEnvironment(Environment environment) { this.environment = environment; } @Override public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
This is the core of logic. The definition of a bean can be manipulated and redefined as a bean factory with attributes, or redefined using the generated class from the interface.
MyCustomBean - simple annotation:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface MyCustomBean { }
Which could annotate the interface:
@MyCustomBean public interface Class1 { }
Solution 2: retrieve the component check
The code that will retrieve packets in @ComponentScan will be more complex.
You must create a BeanDefinitionRegistryPostProcessor and emulate the ConfigurationClassPostProcessor :
Iterate over the bean registry to determine a bean with a declared class that has a ComponentScan attribute, for example (extracted from ConfigurationClassPostProcessor .):
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>(); String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
Extract these attributes as Spring do
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
Then scan the packages and register the bean definition as the first solution