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

com.region.spring.boot.RegionClientAutoConfiguration Maven / Gradle / Ivy

The newest version!
package com.region.spring.boot;

import com.region.core.annotation.Region;
import com.region.core.env.listener.PropertyRefreshListener;
import com.region.http.client.config.ClientConfig;
import com.region.http.client.resolver.parameter.ParameterResolver;
import com.region.http.client.resolver.result.ResultResolver;
import com.region.plugin.Interceptor;
import com.region.spring.RegionClientFactoryBean;
import com.region.spring.client.RegionSpringFactoryBean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.boot.autoconfigure.AutoConfigurationPackages;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ObjectUtils;

import java.util.List;
import java.util.Set;

/**
 * @author liujieyu
 * @date 2024/7/17 20:12
 * @desciption
 */
@Configuration
@Import({RegionClientAutoConfiguration.AutoConfiguredRegionConfigurerRegistrar.class})
@ConditionalOnClass({ClientConfig.class, RegionClientFactoryBean.class})
@EnableConfigurationProperties(RegionAdapterProperties.class)
@ConditionalOnProperty(name = "region.client.enabled", havingValue = "true", matchIfMissing = true)
public class RegionClientAutoConfiguration {

    private final RegionAdapterProperties properties;

    private final Interceptor[] interceptors;

    private final ParameterResolver[] parameterResolvers;

    private final ResultResolver[] resultResolvers;

    private final PropertyRefreshListener[] listeners;

    public RegionClientAutoConfiguration(RegionAdapterProperties properties, ObjectProvider interceptorProvider,
                                         ObjectProvider parameterResolverProvider,
                                         ObjectProvider resultResolverProvider,
                                         ObjectProvider listenerProvider) {
        this.properties = properties;
        this.interceptors = interceptorProvider.getIfAvailable();
        this.parameterResolvers = parameterResolverProvider.getIfAvailable();
        this.resultResolvers = resultResolverProvider.getIfAvailable();
        this.listeners = listenerProvider.getIfAvailable();
    }

    @Bean
    @ConditionalOnMissingBean
    public ClientConfig regionClientConfig() {
        ClientConfig.ClientConfigBuilder builder = ClientConfig
                .builder()
                .loggerAdapter(properties.getLoggerAdapter())
                .jsonAdapter(properties.getJsonAdapter())
                .loadBalancerConfig(properties.getBalancerConfig())
                .cache(properties.getCachePath());
        if (!ObjectUtils.isEmpty(interceptors)) {
            for (Interceptor interceptor : interceptors) {
                builder.interceptor(interceptor);
            }
        }
        if (!ObjectUtils.isEmpty(parameterResolvers)) {
            for (ParameterResolver parameterResolver : parameterResolvers) {
                builder.parameterResolver(parameterResolver);
            }
        }
        if (!ObjectUtils.isEmpty(resultResolvers)) {
            for (ResultResolver resultResolver : resultResolvers) {
                builder.resultResolver(resultResolver);
            }
        }
        if (!ObjectUtils.isEmpty(listeners)) {
            for (PropertyRefreshListener listener : listeners) {
                builder.listener(listener);
            }
        }
        return builder.build();
    }


    @Bean
    @ConditionalOnMissingBean
    public RegionClientFactoryBean regionClientFactoryBean(ClientConfig regionClientConfig) {
        RegionClientFactoryBean regionClientFactoryBean = new RegionClientFactoryBean();
        regionClientFactoryBean.setConfig(regionClientConfig);
        return regionClientFactoryBean;
    }

    public static class AutoConfiguredRegionConfigurerRegistrar implements BeanFactoryAware, EnvironmentAware, ImportBeanDefinitionRegistrar {

        private BeanFactory beanFactory;

        private Environment environment;

        @Override
        public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
            List packages = AutoConfigurationPackages.get(this.beanFactory);
            AutoConfiguredBeanDefinitionScanner scanner = new AutoConfiguredBeanDefinitionScanner(registry);
            packages.add(environment.getProperty("region.client.base-packages"));
            scanner.doScan(packages.toArray(new String[0]));
        }

        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            this.beanFactory = beanFactory;
        }

        @Override
        public void setEnvironment(Environment environment) {
            this.environment = environment;
        }
    }

    public static class AutoConfiguredBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {

        public AutoConfiguredBeanDefinitionScanner(BeanDefinitionRegistry registry) {
            super(registry);
        }

        @Override
        protected Set doScan(String... basePackages) {
            addIncludeFilter(new AnnotationTypeFilter(Region.class));
            addIncludeFilter((metadataReader, metadataReaderFactory) -> true);
            Set beanDefinitionHolders = super.doScan(basePackages);
            if (beanDefinitionHolders != null && !beanDefinitionHolders.isEmpty()) {
                for (BeanDefinitionHolder holder : beanDefinitionHolders) {
                    AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) holder.getBeanDefinition();
                    beanDefinition.getConstructorArgumentValues().addGenericArgumentValue(beanDefinition.getBeanClassName());
                    beanDefinition.setBeanClass(RegionSpringFactoryBean.class);
                    beanDefinition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
                }
            }
            return beanDefinitionHolders;
        }

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

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy