java110 il y a 3 ans
Parent
commit
8366a9b5cc

+ 24 - 0
java110-doc/src/main/java/com/java110/doc/annotation/Java110ApiDocDiscovery.java

@@ -0,0 +1,24 @@
+package com.java110.doc.annotation;
+
+import com.java110.doc.registrar.Java110ApiDocDiscoveryRegistrar;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * 侦听注入
+ * Created by wuxw on 2018/7/2.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import(Java110ApiDocDiscoveryRegistrar.class)
+public @interface Java110ApiDocDiscovery {
+
+    String[] basePackages() default {};
+
+    String[] value() default {};
+
+    Class<?> apiDocClass();
+}

+ 24 - 0
java110-doc/src/main/java/com/java110/doc/annotation/Java110CmdDocDiscovery.java

@@ -0,0 +1,24 @@
+package com.java110.doc.annotation;
+
+import com.java110.doc.registrar.Java110CmdDocDiscoveryRegistrar;
+import org.springframework.context.annotation.Import;
+
+import java.lang.annotation.*;
+
+/**
+ * 侦听注入
+ * Created by wuxw on 2018/7/2.
+ */
+@Target(ElementType.TYPE)
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Import(Java110CmdDocDiscoveryRegistrar.class)
+public @interface Java110CmdDocDiscovery {
+
+    String[] basePackages() default {};
+
+    String[] value() default {};
+
+    Class<?> cmdPublishClass();
+}

+ 63 - 0
java110-doc/src/main/java/com/java110/doc/entity/ApiDocDto.java

@@ -0,0 +1,63 @@
+package com.java110.doc.entity;
+
+import java.io.Serializable;
+
+public class ApiDocDto implements Serializable {
+
+   private String title;
+    /**
+     * description api
+     * @return
+     */
+    private String description;
+
+    /**
+     *  api  version
+     * @return
+     */
+    private  String version;
+
+    private String company;
+
+    public ApiDocDto() {
+    }
+
+    public ApiDocDto(String title, String description, String version, String company) {
+        this.title = title;
+        this.description = description;
+        this.version = version;
+        this.company = company;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public void setDescription(String description) {
+        this.description = description;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public void setVersion(String version) {
+        this.version = version;
+    }
+
+    public String getCompany() {
+        return company;
+    }
+
+    public void setCompany(String company) {
+        this.company = company;
+    }
+}

+ 56 - 0
java110-doc/src/main/java/com/java110/doc/entity/RequestMappingsDocDto.java

@@ -0,0 +1,56 @@
+package com.java110.doc.entity;
+
+import java.io.Serializable;
+
+public class RequestMappingsDocDto implements Serializable {
+
+    private String name;
+
+    private String resource;
+
+    private int seq;
+
+    private String url;
+
+    private String startWay;
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public String getResource() {
+        return resource;
+    }
+
+    public void setResource(String resource) {
+        this.resource = resource;
+    }
+
+    public int getSeq() {
+        return seq;
+    }
+
+    public void setSeq(int seq) {
+        this.seq = seq;
+    }
+
+    public String getUrl() {
+        return url;
+    }
+
+    public void setUrl(String url) {
+        this.url = url;
+    }
+
+    public String getStartWay() {
+        return startWay;
+    }
+
+    public void setStartWay(String startWay) {
+        this.startWay = startWay;
+    }
+}

+ 26 - 0
java110-doc/src/main/java/com/java110/doc/registrar/ApiDocCmdPublishing.java

@@ -0,0 +1,26 @@
+package com.java110.doc.registrar;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 文档 发布类
+ */
+public class ApiDocCmdPublishing {
+
+
+    /**
+     * 保存cmdDocs
+     */
+    private static final List<Map> cmdDocs = new ArrayList<Map>();
+
+    /**
+     * 添加cmd文档
+     *
+     * @param doc
+     */
+    public static void addCmdDoc(Map doc) {
+        cmdDocs.add(doc);
+    }
+}

+ 30 - 0
java110-doc/src/main/java/com/java110/doc/registrar/ApiDocPublishing.java

@@ -0,0 +1,30 @@
+package com.java110.doc.registrar;
+
+import com.java110.doc.entity.ApiDocDto;
+import com.java110.doc.entity.RequestMappingsDocDto;
+
+import java.util.List;
+
+/**
+ * 文档 发布类
+ */
+public class ApiDocPublishing {
+
+    private static ApiDocDto apiDocDto;
+
+
+    /**
+     * 保存cmdDocs
+     */
+    private static List<RequestMappingsDocDto> mappingsDocDtos;
+
+    /**
+     * 添加cmd文档
+     *
+     * @param mappingsDocDtos
+     */
+    public static void setApiDoc(ApiDocDto apiDocDto, List<RequestMappingsDocDto> mappingsDocDtos) {
+        ApiDocPublishing.apiDocDto = apiDocDto;
+        ApiDocPublishing.mappingsDocDtos = mappingsDocDtos;
+    }
+}

+ 212 - 0
java110-doc/src/main/java/com/java110/doc/registrar/Java110ApiDocDiscoveryRegistrar.java

@@ -0,0 +1,212 @@
+package com.java110.doc.registrar;
+
+import com.java110.doc.annotation.Java110ApiDoc;
+import com.java110.doc.annotation.Java110ApiDocDiscovery;
+import com.java110.doc.annotation.Java110RequestMappingsDoc;
+import com.java110.doc.entity.ApiDocDto;
+import com.java110.doc.entity.RequestMappingsDocDto;
+import org.springframework.beans.factory.BeanClassLoaderAware;
+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.ResourceLoaderAware;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * api 文档 注入类
+ * Created by wuxw on 2018/7/2.
+ */
+public class Java110ApiDocDiscoveryRegistrar implements ImportBeanDefinitionRegistrar,ResourceLoaderAware, BeanClassLoaderAware {
+
+    private ResourceLoader resourceLoader;
+
+    private ClassLoader classLoader;
+
+    public Java110ApiDocDiscoveryRegistrar(){
+
+    }
+
+    @Override
+    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+        try {
+            registerListener(importingClassMetadata,registry);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void setBeanClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void setResourceLoader(ResourceLoader resourceLoader) {
+        this.resourceLoader = resourceLoader;
+    }
+
+    /**
+     * 注册侦听
+     * @param metadata
+     * @param registry
+     */
+    public void registerListener(AnnotationMetadata metadata,
+                                 BeanDefinitionRegistry registry) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        ClassPathScanningCandidateComponentProvider scanner = getScanner();
+        scanner.setResourceLoader(this.resourceLoader);
+        Set<String> basePackages;
+        Map<String, Object> attrs = metadata
+                .getAnnotationAttributes(Java110ApiDocDiscovery.class.getName());
+
+        Object cmdPublishClassObj =  attrs.get("apiDocClass");
+
+        //Assert.notNull(cmdPublishClassObj,"Java110CmdDiscovery 没有配置 cmdPublishClass 属性");
+
+        Class<?> cmdPublishClass = (Class<?>) cmdPublishClassObj;
+
+        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
+                Java110ApiDoc.class);
+
+        scanner.addIncludeFilter(annotationTypeFilter);
+        basePackages = getBasePackages(metadata);
+
+        for (String basePackage : basePackages) {
+            Set<BeanDefinition> candidateComponents = scanner
+                    .findCandidateComponents(basePackage);
+            for (BeanDefinition candidateComponent : candidateComponents) {
+                if (candidateComponent instanceof AnnotatedBeanDefinition) {
+                    // verify annotated class is an interface
+                    AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
+                    AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
+
+
+                    Map<String, Object> attributes = annotationMetadata
+                            .getAnnotationAttributes(
+                                    Java110ApiDoc.class.getCanonicalName());
+                    String title = attributes.get("title").toString();
+                    String description = attributes.get("description").toString();
+                    String version = attributes.get("version").toString();
+                    String company = attributes.get("company").toString();
+                    ApiDocDto apiDocDto = new ApiDocDto(title,description,version,company);
+
+                    attributes = annotationMetadata
+                            .getAnnotationAttributes(
+                    Java110RequestMappingsDoc.class.getCanonicalName());
+
+                    attributes.get("mappingsDocs");
+
+
+
+
+                    /*BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
+                    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);*/
+                    Method method = cmdPublishClass.getMethod("setApiDoc", ApiDocDto.class, List.class);
+                    method.invoke(null,apiDocDto,null);
+                }
+            }
+        }
+    }
+
+    protected ClassPathScanningCandidateComponentProvider getScanner() {
+        return new ClassPathScanningCandidateComponentProvider(false) {
+
+            @Override
+            protected boolean isCandidateComponent(
+                    AnnotatedBeanDefinition beanDefinition) {
+                if (beanDefinition.getMetadata().isIndependent()) {
+                    // TODO until SPR-11711 will be resolved
+                    if (beanDefinition.getMetadata().isInterface()
+                            && beanDefinition.getMetadata()
+                            .getInterfaceNames().length == 1
+                            && Annotation.class.getName().equals(beanDefinition
+                            .getMetadata().getInterfaceNames()[0])) {
+                        try {
+                            Class<?> target = ClassUtils.forName(
+                                    beanDefinition.getMetadata().getClassName(),
+                                    Java110ApiDocDiscoveryRegistrar.this.classLoader);
+                            return !target.isAnnotation();
+                        }
+                        catch (Exception ex) {
+                            this.logger.error(
+                                    "Could not load target class: "
+                                            + beanDefinition.getMetadata().getClassName(),
+                                    ex);
+
+                        }
+                    }
+                    return true;
+                }
+                return false;
+
+            }
+        };
+    }
+
+    protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
+        Map<String, Object> attributes = importingClassMetadata
+                .getAnnotationAttributes(Java110ApiDocDiscovery.class.getCanonicalName());
+
+        Set<String> basePackages = new HashSet<String>();
+        for (String pkg : (String[]) attributes.get("value")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+        for (String pkg : (String[]) attributes.get("basePackages")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+        if (basePackages.isEmpty()) {
+            basePackages.add(
+                    ClassUtils.getPackageName(importingClassMetadata.getClassName()));
+        }
+        return basePackages;
+    }
+
+
+    /**
+     * 获取名称
+     * @param listeners
+     * @param beanDefinition
+     * @return
+     */
+    private String getListenerName(Map<String, Object> listeners,AnnotatedBeanDefinition beanDefinition) {
+        if (listeners == null) {
+            String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
+            return Introspector.decapitalize(shortClassName);
+        }
+        String value = (String) listeners.get("value");
+        if (!StringUtils.hasText(value)) {
+            value = (String) listeners.get("name");
+        }
+        if (StringUtils.hasText(value)) {
+            return value;
+        }
+
+        String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
+        value = Introspector.decapitalize(shortClassName);
+        return value;
+    }
+
+
+}

+ 199 - 0
java110-doc/src/main/java/com/java110/doc/registrar/Java110CmdDocDiscoveryRegistrar.java

@@ -0,0 +1,199 @@
+package com.java110.doc.registrar;
+
+import com.java110.doc.annotation.Java110ApiDoc;
+import com.java110.doc.annotation.Java110CmdDoc;
+import com.java110.doc.annotation.Java110CmdDocDiscovery;
+import org.springframework.beans.factory.BeanClassLoaderAware;
+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.ResourceLoaderAware;
+import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
+import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
+import org.springframework.core.io.ResourceLoader;
+import org.springframework.core.type.AnnotationMetadata;
+import org.springframework.core.type.filter.AnnotationTypeFilter;
+import org.springframework.util.ClassUtils;
+import org.springframework.util.StringUtils;
+
+import java.beans.Introspector;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * api 文档 注入类
+ * Created by wuxw on 2018/7/2.
+ */
+public class Java110CmdDocDiscoveryRegistrar implements ImportBeanDefinitionRegistrar,ResourceLoaderAware, BeanClassLoaderAware {
+
+    private ResourceLoader resourceLoader;
+
+    private ClassLoader classLoader;
+
+    public Java110CmdDocDiscoveryRegistrar(){
+
+    }
+
+    @Override
+    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
+        try {
+            registerListener(importingClassMetadata,registry);
+        } catch (NoSuchMethodException e) {
+            e.printStackTrace();
+        } catch (InvocationTargetException e) {
+            e.printStackTrace();
+        } catch (IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void setBeanClassLoader(ClassLoader classLoader) {
+        this.classLoader = classLoader;
+    }
+
+    @Override
+    public void setResourceLoader(ResourceLoader resourceLoader) {
+        this.resourceLoader = resourceLoader;
+    }
+
+    /**
+     * 注册侦听
+     * @param metadata
+     * @param registry
+     */
+    public void registerListener(AnnotationMetadata metadata,
+                                 BeanDefinitionRegistry registry) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        ClassPathScanningCandidateComponentProvider scanner = getScanner();
+        scanner.setResourceLoader(this.resourceLoader);
+        Set<String> basePackages;
+        Map<String, Object> attrs = metadata
+                .getAnnotationAttributes(Java110CmdDocDiscovery.class.getName());
+
+        Object cmdPublishClassObj =  attrs.get("cmdPublishClass");
+
+        //Assert.notNull(cmdPublishClassObj,"Java110CmdDiscovery 没有配置 cmdPublishClass 属性");
+
+        Class<?> cmdPublishClass = (Class<?>) cmdPublishClassObj;
+
+        AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
+                Java110ApiDoc.class);
+
+        scanner.addIncludeFilter(annotationTypeFilter);
+        basePackages = getBasePackages(metadata);
+
+        for (String basePackage : basePackages) {
+            Set<BeanDefinition> candidateComponents = scanner
+                    .findCandidateComponents(basePackage);
+            for (BeanDefinition candidateComponent : candidateComponents) {
+                if (candidateComponent instanceof AnnotatedBeanDefinition) {
+                    // verify annotated class is an interface
+                    AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
+                    AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
+
+
+                    Map<String, Object> attributes = annotationMetadata
+                            .getAnnotationAttributes(
+                                    Java110CmdDoc.class.getCanonicalName());
+
+                    String beanName = getListenerName(attributes,beanDefinition);
+                    String serviceCode = attributes.get("serviceCode").toString();
+
+
+                    /*BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
+                    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);*/
+//                    Method method = cmdPublishClass.getMethod("addListener", CmdListenerDto.class);
+//                    method.invoke(null,new CmdListenerDto(beanName,serviceCode));
+                }
+            }
+        }
+    }
+
+    protected ClassPathScanningCandidateComponentProvider getScanner() {
+        return new ClassPathScanningCandidateComponentProvider(false) {
+
+            @Override
+            protected boolean isCandidateComponent(
+                    AnnotatedBeanDefinition beanDefinition) {
+                if (beanDefinition.getMetadata().isIndependent()) {
+                    // TODO until SPR-11711 will be resolved
+                    if (beanDefinition.getMetadata().isInterface()
+                            && beanDefinition.getMetadata()
+                            .getInterfaceNames().length == 1
+                            && Annotation.class.getName().equals(beanDefinition
+                            .getMetadata().getInterfaceNames()[0])) {
+                        try {
+                            Class<?> target = ClassUtils.forName(
+                                    beanDefinition.getMetadata().getClassName(),
+                                    Java110CmdDocDiscoveryRegistrar.this.classLoader);
+                            return !target.isAnnotation();
+                        }
+                        catch (Exception ex) {
+                            this.logger.error(
+                                    "Could not load target class: "
+                                            + beanDefinition.getMetadata().getClassName(),
+                                    ex);
+
+                        }
+                    }
+                    return true;
+                }
+                return false;
+
+            }
+        };
+    }
+
+    protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
+        Map<String, Object> attributes = importingClassMetadata
+                .getAnnotationAttributes(Java110CmdDocDiscovery.class.getCanonicalName());
+
+        Set<String> basePackages = new HashSet<String>();
+        for (String pkg : (String[]) attributes.get("value")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+        for (String pkg : (String[]) attributes.get("basePackages")) {
+            if (StringUtils.hasText(pkg)) {
+                basePackages.add(pkg);
+            }
+        }
+        if (basePackages.isEmpty()) {
+            basePackages.add(
+                    ClassUtils.getPackageName(importingClassMetadata.getClassName()));
+        }
+        return basePackages;
+    }
+
+
+    /**
+     * 获取名称
+     * @param listeners
+     * @param beanDefinition
+     * @return
+     */
+    private String getListenerName(Map<String, Object> listeners,AnnotatedBeanDefinition beanDefinition) {
+        if (listeners == null) {
+            String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
+            return Introspector.decapitalize(shortClassName);
+        }
+        String value = (String) listeners.get("value");
+        if (!StringUtils.hasText(value)) {
+            value = (String) listeners.get("name");
+        }
+        if (StringUtils.hasText(value)) {
+            return value;
+        }
+
+        String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
+        value = Introspector.decapitalize(shortClassName);
+        return value;
+    }
+
+
+}

+ 5 - 0
service-api/src/main/java/com/java110/api/ApiApplicationStart.java

@@ -21,6 +21,8 @@ import com.java110.core.trace.Java110RestTemplateInterceptor;
 import com.java110.core.client.RestTemplate;
 import com.java110.core.event.service.api.ServiceDataFlowEventPublishing;
 import com.java110.core.log.LoggerFactory;
+import com.java110.doc.annotation.Java110ApiDocDiscovery;
+import com.java110.doc.registrar.ApiDocPublishing;
 import com.java110.service.init.ServiceStartInit;
 import io.swagger.annotations.ApiOperation;
 import okhttp3.ConnectionPool;
@@ -91,6 +93,9 @@ import java.util.concurrent.TimeUnit;
 })
 @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
 @EnableAsync
+
+//文档
+@Java110ApiDocDiscovery(basePackages = {"com.java110.api.rest"},apiDocClass = ApiDocPublishing.class)
 public class ApiApplicationStart {
 
     private static Logger logger = LoggerFactory.getLogger(ApiApplicationStart.class);