All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.hiboot.mcn.autoconfigure.config.ComponentScanPackageCheck Maven / Gradle / Ivy

package cn.hiboot.mcn.autoconfigure.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * ComponentScanPackageCheck
 *
 * @author DingHao
 * @since 2022/7/14 17:41
 */
public class ComponentScanPackageCheck {
    private final Logger log = LoggerFactory.getLogger(ComponentScanPackageCheck.class);

    private static final Set PROBLEM_PACKAGES = new HashSet<>();

    public ComponentScanPackageCheck(){
        PROBLEM_PACKAGES.add("cn");
        PROBLEM_PACKAGES.add("cn.hiboot");
    }

    public void check(BeanDefinitionRegistry registry) {
        String message = getWarning(registry);
        if (StringUtils.hasLength(message)) {
            log.warn(String.format("%n%n** WARNING ** : %s%n%n", message));
        }
    }

    private String getWarning(BeanDefinitionRegistry registry) {
        Set scannedPackages = getComponentScanningPackages(registry);
        List problematicPackages = getProblematicPackages(scannedPackages);
        if (problematicPackages.isEmpty()) {
            return null;
        }
        return "Your ApplicationContext is unlikely to start due to a @ComponentScan of "
                + StringUtils.collectionToDelimitedString(problematicPackages, ", ") + ".";
    }

    private Set getComponentScanningPackages(BeanDefinitionRegistry registry) {
        Set packages = new LinkedHashSet<>();
        String[] names = registry.getBeanDefinitionNames();
        for (String name : names) {
            BeanDefinition definition = registry.getBeanDefinition(name);
            if (definition instanceof AnnotatedBeanDefinition annotatedDefinition) {
                addComponentScanningPackages(packages, annotatedDefinition.getMetadata());
            }
        }
        return packages;
    }

    private void addComponentScanningPackages(Set packages, AnnotationMetadata metadata) {
        AnnotationAttributes attributes = AnnotationAttributes
                .fromMap(metadata.getAnnotationAttributes(ComponentScan.class.getName(), true));
        if (attributes != null) {
            addPackages(packages, attributes.getStringArray("value"));
            addPackages(packages, attributes.getStringArray("basePackages"));
            addClasses(packages, attributes.getStringArray("basePackageClasses"));
            if (packages.isEmpty()) {
                packages.add(ClassUtils.getPackageName(metadata.getClassName()));
            }
        }
    }

    private void addPackages(Set packages, String[] values) {
        if (values != null) {
            Collections.addAll(packages, values);
        }
    }

    private void addClasses(Set packages, String[] values) {
        if (values != null) {
            for (String value : values) {
                packages.add(ClassUtils.getPackageName(value));
            }
        }
    }

    private List getProblematicPackages(Set scannedPackages) {
        List problematicPackages = new ArrayList<>();
        for (String scannedPackage : scannedPackages) {
            if (isProblematicPackage(scannedPackage)) {
                problematicPackages.add(getDisplayName(scannedPackage));
            }
        }
        return problematicPackages;
    }

    private boolean isProblematicPackage(String scannedPackage) {
        if (scannedPackage == null || scannedPackage.isEmpty()) {
            return true;
        }
        return PROBLEM_PACKAGES.contains(scannedPackage);
    }

    private String getDisplayName(String scannedPackage) {
        if (scannedPackage == null || scannedPackage.isEmpty()) {
            return "the default package";
        }
        return "'" + scannedPackage + "'";
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy