Home > OS >  Fix SonarQube code smell of lambdas reference to a private non-static method
Fix SonarQube code smell of lambdas reference to a private non-static method

Time:03-10

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

  • Related