修复对私有非静态方法的 lambda 引用的 SonarQube 代码味道
Fix SonarQube code smell of lambdas reference to a private non-static method
我用 SonarQube 扫描了我的代码,然后修复了很多代码异味。但是只有一行我不太确定是不是误报:
我使用流 API 来处理 basePackages,几乎所有的管道都是方法引用而不是 lambda。但是只有一行代码我不确定如何修复它:.map(p -> findCandidateComponents(p))
显然 String.class
没有提供像我的自定义方法 findCandidateComponents()
那样的方法来扫描具有给定包名称的组件,我必须在管道上放置一个 lambda。
大家有什么建议吗?谢谢
@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 = }
}
正如 find Candidate Components 实例方法一样 class。您可以通过它的对象来引用它。
.map(p -> findCandidateComponents(p))
这可以替换为
.map(this::findCandidateComponents)
请参考https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
我用 SonarQube 扫描了我的代码,然后修复了很多代码异味。但是只有一行我不太确定是不是误报:
我使用流 API 来处理 basePackages,几乎所有的管道都是方法引用而不是 lambda。但是只有一行代码我不确定如何修复它:.map(p -> findCandidateComponents(p))
显然 String.class
没有提供像我的自定义方法 findCandidateComponents()
那样的方法来扫描具有给定包名称的组件,我必须在管道上放置一个 lambda。
大家有什么建议吗?谢谢
@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 = }
}
正如 find Candidate Components 实例方法一样 class。您可以通过它的对象来引用它。
.map(p -> findCandidateComponents(p))
这可以替换为
.map(this::findCandidateComponents)
请参考https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html