@Component
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class MyTypeIncludeFilter extends TypeExcludeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
log.info("hello world")
return false;
}
}
@SpringBootApplication(
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}
My custom TypeIncludeFilter don‘t take effect,then I see the code for springboot-2.27 and latest version;
public class TypeExcludeFilter implements TypeFilter, BeanFactoryAware {
private BeanFactory beanFactory;
private Collection<TypeExcludeFilter> delegates;
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
if (this.beanFactory instanceof ListableBeanFactory && getClass() == TypeExcludeFilter.class) {
for (TypeExcludeFilter delegate : getDelegates()) {
if (delegate.match(metadataReader, metadataReaderFactory)) {
return true;
}
}
}
return false;
}
private Collection<TypeExcludeFilter> getDelegates() {
Collection<TypeExcludeFilter> delegates = this.delegates;
if (delegates == null) {
delegates = ((ListableBeanFactory) this.beanFactory).getBeansOfType(TypeExcludeFilter.class).values();
this.delegates = delegates;
}
return delegates;
}
@Override
public boolean equals(Object obj) {
throw new IllegalStateException("TypeExcludeFilter " + getClass() + " has not implemented equals");
}
@Override
public int hashCode() {
throw new IllegalStateException("TypeExcludeFilter " + getClass() + " has not implemented hashCode");
}
}
Reason: ConfigurationClassPostProcessor is BeanDefinitionRegistryPostProcessor and It calls the "TypeExcludeFilter#match" method when it starts scanning packages to generate bean definitions, but at this point my typeExcludeFilter has not generated bean Definetion. So the Beanfacory get bean for typeExcludeFilter is an empty collection and cache it。After that ,each judgment will not get a real bean every time from cache.
Comment From: bclozel
TypeExcludeFilter
implementations are not meant to be application components; as you've found out, they would be involved too late in the process. You can trigger such filters by declaring them on annotations such as @TypeExcludeFilters
or @ComponentScan
as explained in its javadoc.