I scanned my code with SonarQube and then I fixed a lot of code smells. But there is just one line that I am not quite sure is it a false positive:
I use stream API to handle basePackages, and nearly all the pipelines is method reference rather than lambda. but there is just one line of code I am not sure how to fix it: .map(p -> findCandidateComponents(p))
Obviously String.class
doesn't provider a method like my custom one findCandidateComponents()
to scan components with given package name, I must have to put a lambda on the pipeline.
Any suggestions guys? Thanks.
@Slf4j
@Configuration
public class FeignConfig implements BeanFactoryPostProcessor, ResourceLoaderAware, EnvironmentAware {
private Environment env;
private ResourceLoader resourceLoader;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
List<String> basePackages = Optional.ofNullable(env.getProperty("some.package-names"))
.map(s -> Arrays.asList(s.split("\\,")))
.orElse(Collections.emptyList());
basePackages.stream()
.map(p -> findCandidateComponents(p))//██████████ Lambdas should be replaced with method references ██████████
.flatMap(Collection::stream)
.filter(AnnotatedBeanDefinition.class::isInstance)
.map(AnnotatedBeanDefinition.class::cast)
.map(AnnotatedBeanDefinition::getMetadata)
.filter(AnnotationMetadata::isInterface)
.forEach(meta -> {
try {
Class<?> clientInterface = Class.forName(meta.getClassName());
MyFeignClient annotation = clientInterface.getAnnotation(MyFeignClient.class);
Object bean = buildFeignClient(clientInterface, annotation.url());
configurableListableBeanFactory.registerSingleton(clientInterface.getName(), bean);
} catch (Exception e) {
log.warn("Failed to register interfaces with @MyFeignClient", e);
}
});
}
private Set<BeanDefinition> findCandidateComponents(String basePackage) {
ClassPathScanningCandidateComponentProvider scanner = getScanner();
scanner.setResourceLoader(resourceLoader);
AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(MyFeignClient.class);
scanner.addIncludeFilter(annotationTypeFilter);
return scanner.findCandidateComponents(basePackage);
}
private ClassPathScanningCandidateComponentProvider getScanner() {
return new ClassPathScanningCandidateComponentProvider(false, env) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
if (!beanDefinition.getMetadata().isIndependent()) {
return false;
}
return !beanDefinition.getMetadata().isAnnotation();
}
};
}
@Override
public void setEnvironment(Environment env) { this.env = env; }
@Override
public void setResourceLoader(ResourceLoader resourceLoader) { this.resourceLoader = }
}
CodePudding user response:
As findCandidateComponents instace method is present in the same class. You can refer it by its object.
.map(p -> findCandidateComponents(p))
This can be replaced with
.map(this::findCandidateComponents)
Please refer https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html