123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- package cn.nosum.support.config;
- import cn.nosum.support.annotation.DynamicClient;
- import cn.nosum.support.annotation.EnableDynamicClients;
- import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
- import org.springframework.beans.factory.config.BeanDefinition;
- import org.springframework.beans.factory.config.BeanDefinitionHolder;
- import org.springframework.beans.factory.support.AbstractBeanDefinition;
- import org.springframework.beans.factory.support.BeanDefinitionBuilder;
- import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
- import org.springframework.beans.factory.support.BeanDefinitionRegistry;
- import org.springframework.context.EnvironmentAware;
- import org.springframework.context.ResourceLoaderAware;
- import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
- import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
- import org.springframework.core.env.Environment;
- import org.springframework.core.io.ResourceLoader;
- import org.springframework.core.type.AnnotationMetadata;
- import org.springframework.core.type.filter.AnnotationTypeFilter;
- import org.springframework.util.Assert;
- import org.springframework.util.ClassUtils;
- import org.springframework.util.StringUtils;
- import java.util.HashSet;
- import java.util.Map;
- import java.util.Set;
- /**
- * Dynamic class registration.
- *
- * @author Young
- */
- public class DynamicClientRegistrar implements ImportBeanDefinitionRegistrar , ResourceLoaderAware, EnvironmentAware {
- private ResourceLoader resourceLoader;
- private Environment environment;
- @Override
- public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
- this.registerClients(metadata,registry);
- }
- public void registerClients(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
- ClassPathScanningCandidateComponentProvider scanner = getScanner();
- scanner.setResourceLoader(this.resourceLoader);
- Set<String> basePackages = getBasePackages(metadata);;
- AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(DynamicClient.class);
- scanner.addIncludeFilter(annotationTypeFilter);
- 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();
- Assert.isTrue(annotationMetadata.isInterface(), "@FeignClient can only be specified on an interface");
- Map<String, Object> attributes = annotationMetadata.getAnnotationAttributes(DynamicClient.class.getCanonicalName());
- assert attributes != null;
- registerFeignClient(registry, annotationMetadata, attributes);
- }
- }
- }
- }
- private void registerFeignClient(BeanDefinitionRegistry registry,
- AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
- String name = (String) attributes.get("name");
- if (!StringUtils.hasText(name)){
- name = annotationMetadata.getClassName();
- }
- BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(DynamicClientFactoryBean.class);
- definition.addPropertyValue("name", name);
- definition.addPropertyValue("type", annotationMetadata.getClassName());
- definition.addPropertyValue("refName",attributes.get("refName"));
- definition.addPropertyValue("refType",attributes.get("refType"));
- definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
- String alias = name + "DynamicClient";
- AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
- // has a default, won't be
- boolean primary = (Boolean) attributes.get("primary");
- // null
- beanDefinition.setPrimary(primary);
- String qualifier = getQualifier(attributes);
- if (StringUtils.hasText(qualifier)) {
- alias = qualifier;
- }
- BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, name, new String[] { alias });
- BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
- }
- protected ClassPathScanningCandidateComponentProvider getScanner() {
- return new ClassPathScanningCandidateComponentProvider(false, this.environment) {
- @Override
- protected boolean isCandidateComponent(
- AnnotatedBeanDefinition beanDefinition) {
- boolean isCandidate = false;
- if (beanDefinition.getMetadata().isIndependent()) {
- if (!beanDefinition.getMetadata().isAnnotation()) {
- isCandidate = true;
- }
- }
- return isCandidate;
- }
- };
- }
- private String getQualifier(Map<String, Object> client) {
- if (client == null) {
- return null;
- }
- String qualifier = (String) client.get("qualifier");
- if (StringUtils.hasText(qualifier)) {
- return qualifier;
- }
- return null;
- }
- protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
- Map<String, Object> attributes = importingClassMetadata
- .getAnnotationAttributes(EnableDynamicClients.class.getCanonicalName());
- Set<String> basePackages = new HashSet<>();
- 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);
- }
- }
- for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
- basePackages.add(ClassUtils.getPackageName(clazz));
- }
- if (basePackages.isEmpty()) {
- basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
- }
- return basePackages;
- }
- @Override
- public void setResourceLoader(ResourceLoader resourceLoader) {
- this.resourceLoader = resourceLoader;
- }
- @Override
- public void setEnvironment(Environment environment) {
- this.environment = environment;
- }
- }
|