Java110ApiDocDiscoveryRegistrar.java 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. package com.java110.doc.registrar;
  2. import com.java110.doc.annotation.Java110ApiDoc;
  3. import com.java110.doc.annotation.Java110ApiDocDiscovery;
  4. import com.java110.doc.annotation.Java110RequestMappingsDoc;
  5. import com.java110.doc.entity.ApiDocDto;
  6. import com.java110.doc.entity.RequestMappingsDocDto;
  7. import org.springframework.beans.factory.BeanClassLoaderAware;
  8. import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
  9. import org.springframework.beans.factory.config.BeanDefinition;
  10. import org.springframework.beans.factory.support.BeanDefinitionRegistry;
  11. import org.springframework.context.ResourceLoaderAware;
  12. import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
  13. import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
  14. import org.springframework.core.annotation.AnnotationAttributes;
  15. import org.springframework.core.io.ResourceLoader;
  16. import org.springframework.core.type.AnnotationMetadata;
  17. import org.springframework.core.type.filter.AnnotationTypeFilter;
  18. import org.springframework.util.ClassUtils;
  19. import org.springframework.util.StringUtils;
  20. import java.beans.Introspector;
  21. import java.lang.annotation.Annotation;
  22. import java.lang.reflect.InvocationTargetException;
  23. import java.lang.reflect.Method;
  24. import java.util.*;
  25. /**
  26. * api 文档 注入类
  27. * Created by wuxw on 2018/7/2.
  28. */
  29. public class Java110ApiDocDiscoveryRegistrar implements ImportBeanDefinitionRegistrar,ResourceLoaderAware, BeanClassLoaderAware {
  30. private ResourceLoader resourceLoader;
  31. private ClassLoader classLoader;
  32. public Java110ApiDocDiscoveryRegistrar(){
  33. }
  34. @Override
  35. public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
  36. try {
  37. registerListener(importingClassMetadata,registry);
  38. } catch (NoSuchMethodException e) {
  39. e.printStackTrace();
  40. } catch (InvocationTargetException e) {
  41. e.printStackTrace();
  42. } catch (IllegalAccessException e) {
  43. e.printStackTrace();
  44. }
  45. }
  46. @Override
  47. public void setBeanClassLoader(ClassLoader classLoader) {
  48. this.classLoader = classLoader;
  49. }
  50. @Override
  51. public void setResourceLoader(ResourceLoader resourceLoader) {
  52. this.resourceLoader = resourceLoader;
  53. }
  54. /**
  55. * 注册侦听
  56. * @param metadata
  57. * @param registry
  58. */
  59. public void registerListener(AnnotationMetadata metadata,
  60. BeanDefinitionRegistry registry) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
  61. ClassPathScanningCandidateComponentProvider scanner = getScanner();
  62. scanner.setResourceLoader(this.resourceLoader);
  63. Set<String> basePackages;
  64. Map<String, Object> attrs = metadata
  65. .getAnnotationAttributes(Java110ApiDocDiscovery.class.getName());
  66. Object cmdPublishClassObj = attrs.get("apiDocClass");
  67. //Assert.notNull(cmdPublishClassObj,"Java110CmdDiscovery 没有配置 cmdPublishClass 属性");
  68. Class<?> cmdPublishClass = (Class<?>) cmdPublishClassObj;
  69. AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
  70. Java110ApiDoc.class);
  71. scanner.addIncludeFilter(annotationTypeFilter);
  72. basePackages = getBasePackages(metadata);
  73. for (String basePackage : basePackages) {
  74. Set<BeanDefinition> candidateComponents = scanner
  75. .findCandidateComponents(basePackage);
  76. for (BeanDefinition candidateComponent : candidateComponents) {
  77. if (candidateComponent instanceof AnnotatedBeanDefinition) {
  78. // verify annotated class is an interface
  79. AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
  80. AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
  81. Map<String, Object> attributes = annotationMetadata
  82. .getAnnotationAttributes(
  83. Java110ApiDoc.class.getCanonicalName());
  84. String title = attributes.get("title").toString();
  85. String description = attributes.get("description").toString();
  86. String version = attributes.get("version").toString();
  87. String company = attributes.get("company").toString();
  88. ApiDocDto apiDocDto = new ApiDocDto(title,description,version,company);
  89. attributes = annotationMetadata
  90. .getAnnotationAttributes(
  91. Java110RequestMappingsDoc.class.getCanonicalName());
  92. List<Map<String,Object>> mappingAttrs = (List<Map<String,Object>>)attributes.get("mappingsDocs");
  93. List<RequestMappingsDocDto> mappingsDocDtos = new ArrayList<>();
  94. RequestMappingsDocDto requestMappingsDocDto = null;
  95. for(Map<String,Object> mappingAttr : mappingAttrs){
  96. requestMappingsDocDto = new RequestMappingsDocDto(mappingAttr.get("name").toString(),mappingAttr.get("resource").toString(),
  97. Integer.parseInt(mappingAttr.get("seq").toString()),mappingAttr.get("url").toString(),mappingAttr.get("startWay").toString()
  98. );
  99. mappingsDocDtos.add(requestMappingsDocDto);
  100. }
  101. /*BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(beanDefinition, beanName);
  102. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);*/
  103. Method method = cmdPublishClass.getMethod("setApiDoc", ApiDocDto.class, List.class);
  104. method.invoke(null,apiDocDto,mappingsDocDtos);
  105. }
  106. }
  107. }
  108. }
  109. protected ClassPathScanningCandidateComponentProvider getScanner() {
  110. return new ClassPathScanningCandidateComponentProvider(false) {
  111. @Override
  112. protected boolean isCandidateComponent(
  113. AnnotatedBeanDefinition beanDefinition) {
  114. if (beanDefinition.getMetadata().isIndependent()) {
  115. // TODO until SPR-11711 will be resolved
  116. if (beanDefinition.getMetadata().isInterface()
  117. && beanDefinition.getMetadata()
  118. .getInterfaceNames().length == 1
  119. && Annotation.class.getName().equals(beanDefinition
  120. .getMetadata().getInterfaceNames()[0])) {
  121. try {
  122. Class<?> target = ClassUtils.forName(
  123. beanDefinition.getMetadata().getClassName(),
  124. Java110ApiDocDiscoveryRegistrar.this.classLoader);
  125. return !target.isAnnotation();
  126. }
  127. catch (Exception ex) {
  128. this.logger.error(
  129. "Could not load target class: "
  130. + beanDefinition.getMetadata().getClassName(),
  131. ex);
  132. }
  133. }
  134. return true;
  135. }
  136. return false;
  137. }
  138. };
  139. }
  140. protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
  141. Map<String, Object> attributes = importingClassMetadata
  142. .getAnnotationAttributes(Java110ApiDocDiscovery.class.getCanonicalName());
  143. Set<String> basePackages = new HashSet<String>();
  144. for (String pkg : (String[]) attributes.get("value")) {
  145. if (StringUtils.hasText(pkg)) {
  146. basePackages.add(pkg);
  147. }
  148. }
  149. for (String pkg : (String[]) attributes.get("basePackages")) {
  150. if (StringUtils.hasText(pkg)) {
  151. basePackages.add(pkg);
  152. }
  153. }
  154. if (basePackages.isEmpty()) {
  155. basePackages.add(
  156. ClassUtils.getPackageName(importingClassMetadata.getClassName()));
  157. }
  158. return basePackages;
  159. }
  160. /**
  161. * 获取名称
  162. * @param listeners
  163. * @param beanDefinition
  164. * @return
  165. */
  166. private String getListenerName(Map<String, Object> listeners,AnnotatedBeanDefinition beanDefinition) {
  167. if (listeners == null) {
  168. String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
  169. return Introspector.decapitalize(shortClassName);
  170. }
  171. String value = (String) listeners.get("value");
  172. if (!StringUtils.hasText(value)) {
  173. value = (String) listeners.get("name");
  174. }
  175. if (StringUtils.hasText(value)) {
  176. return value;
  177. }
  178. String shortClassName = ClassUtils.getShortName(beanDefinition.getBeanClassName());
  179. value = Introspector.decapitalize(shortClassName);
  180. return value;
  181. }
  182. }