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

com.dtflys.forest.scanner.ClassPathClientScanner Maven / Gradle / Ivy

package com.dtflys.forest.scanner;

import com.dtflys.forest.annotation.BaseLifeCycle;
import com.dtflys.forest.annotation.MethodLifeCycle;
import com.dtflys.forest.file.SpringResource;
import com.dtflys.forest.http.body.MultipartRequestBodyBuilder;
import com.dtflys.forest.http.body.RequestBodyBuilder;
import com.dtflys.forest.http.body.ResourceRequestBodyBuilder;
import com.dtflys.forest.multipart.ForestMultipartFactory;
import com.dtflys.forest.utils.ClientFactoryBeanUtils;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.core.io.Resource;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;

import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * @author gongjun[[email protected]]
 * @since 2017-04-24 14:46
 */
public class ClassPathClientScanner extends ClassPathBeanDefinitionScanner {

    private final static String[] FOREST_METHOD_ANNOTATION_NAMES = new String[] {
            "com.dtflys.forest.annotation.Backend",
            "com.dtflys.forest.annotation.Headers",
            "com.dtflys.forest.annotation.Address",
            "com.dtflys.forest.annotation.Request",
            "com.dtflys.forest.annotation.Get",
            "com.dtflys.forest.annotation.GetRequest",
            "com.dtflys.forest.annotation.Post",
            "com.dtflys.forest.annotation.PostRequest",
            "com.dtflys.forest.annotation.Put",
            "com.dtflys.forest.annotation.PutRequest",
            "com.dtflys.forest.annotation.HeadRequest",
            "com.dtflys.forest.annotation.Options",
            "com.dtflys.forest.annotation.OptionsRequest",
            "com.dtflys.forest.annotation.Patch",
            "com.dtflys.forest.annotation.PatchRequest",
            "com.dtflys.forest.annotation.Trace",
            "com.dtflys.forest.annotation.TraceRequest",
    } ;


    private final String configurationId;

    private boolean allInterfaces = true;

    public ClassPathClientScanner(String configurationId, BeanDefinitionRegistry registry) {
        super(registry, false);
        this.configurationId = configurationId;
        registerFilters();
        registerMultipartTypes();
    }

    /**
     * 注册能上传下载的文件类型
     */
    public void registerMultipartTypes() {
        ForestMultipartFactory.registerFactory(Resource.class, SpringResource.class);
        RequestBodyBuilder.registerBodyBuilder(Resource.class, new ResourceRequestBodyBuilder());
        try {
            Class multipartFileClass = Class.forName("org.springframework.web.multipart.MultipartFile");
            Class springMultipartFileClass = Class.forName("com.dtflys.forest.file.SpringMultipartFile");
            ForestMultipartFactory.registerFactory(multipartFileClass, springMultipartFileClass);
            RequestBodyBuilder.registerBodyBuilder(multipartFileClass, new MultipartRequestBodyBuilder());
        } catch (Throwable th) {
        }
    }

    private boolean interfaceFilter(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) {
        ClassMetadata classMetadata = metadataReader.getClassMetadata();
        if (!classMetadata.isInterface() || classMetadata.isFinal()) {
            return false;
        }

        String[] superClassNames = metadataReader.getClassMetadata().getInterfaceNames();
        boolean hasSuperForestClient = false;
        for (String superClassName : superClassNames) {
            try {
                MetadataReader superMetaReader = metadataReaderFactory.getMetadataReader(superClassName);
                hasSuperForestClient = interfaceFilter(superMetaReader, metadataReaderFactory);
            } catch (IOException e) {
            }
            if (hasSuperForestClient) {
                return true;
            }
        }

        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        for (String annotationTypeName : annotationMetadata.getAnnotationTypes()) {
            if ("com.dtflys.forest.annotation.ForestClient".equals(annotationTypeName)) {
                return true;
            }
            if ("com.dtflys.forest.annotation.BaseRequest".equals(annotationTypeName)) {
                return true;
            }
        }
        for (String methodAnnName : FOREST_METHOD_ANNOTATION_NAMES) {
            if (annotationMetadata.hasAnnotatedMethods(methodAnnName)) {
                return true;
            }
        }

/*
        Set baseAnnNames = annotationMetadata.getAnnotationTypes();
        for (String annName : baseAnnNames) {
            try {
                Class annType = Class.forName(annName);
                Annotation lcAnn = annType.getAnnotation(BaseLifeCycle.class);
                if (lcAnn != null) {
                    return true;
                }
                lcAnn = annType.getAnnotation(MethodLifeCycle.class);
                if (lcAnn != null) {
                    return true;
                }
            } catch (Throwable ignored) {
            }
        }
*/
        return false;
    }

    /**
     * 注册过滤器
     */
    public void registerFilters() {
        if (allInterfaces) {
            // include all interfaces
            addIncludeFilter((metadataReader, metadataReaderFactory) ->
                    interfaceFilter(metadataReader, metadataReaderFactory));
        }

        // exclude package-info.java
        addExcludeFilter((metadataReader, metadataReaderFactory) -> {
            String className = metadataReader.getClassMetadata().getClassName();
            return className.endsWith("package-info");
        });
    }

    private void processBeanDefinitions(Set beanDefinitions) {
        GenericBeanDefinition definition;
        for (BeanDefinitionHolder holder : beanDefinitions) {
            definition = (GenericBeanDefinition) holder.getBeanDefinition();
            String beanClassName = definition.getBeanClassName();
            ClientFactoryBeanUtils.setupClientFactoryBean(definition, configurationId, beanClassName);
            logger.info("[Forest] Created Forest Client Bean with name '" + holder.getBeanName()
                    + "' and Proxy of '" + beanClassName + "' client interface");

        }
    }


    /**
     * 重写扫描逻辑
     * @param basePackages 请求接口类所在的包路径,只能是第一层的包,不包含子包
     * @return BeanDefinitionHolder实例集合
     */
    @Override
    public Set doScan(String... basePackages) {
        Set beanDefinitions = super.doScan(basePackages);
        if (!beanDefinitions.isEmpty()) {
            processBeanDefinitions(beanDefinitions);
        }
        return beanDefinitions;
    }

    @Override
    protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
        return beanDefinition.getMetadata().isInterface() && beanDefinition.getMetadata().isIndependent();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy