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

com.github.bootfastconfig.cache.BindScannerRegistrar Maven / Gradle / Ivy

Go to download

Parent pom providing dependency and plugin management for applications built with Maven

The newest version!
package com.github.bootfastconfig.cache;


import com.github.bootfastconfig.springtool.ClassUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
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.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
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.classreading.MetadataReader;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @author mister
 */
@Slf4j
@Configuration
public class BindScannerRegistrar implements ImportBeanDefinitionRegistrar,
        ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

    protected final Log logger = LogFactory.getLog(getClass());
    private ResourceLoader resourceLoader;

    private ClassLoader classLoader;

    private Environment environment;

    public BindScannerRegistrar() {
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }

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


    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        Map annotationAttributes = importingClassMetadata.getAnnotationAttributes(EnableCaching.class.getName(), false);
        if (annotationAttributes == null) {
            return;
        }

        Set cacheSimpleConfigs = findCacheSimpleConfigAnnotation(importingClassMetadata);
        registerConfigCacheService(registry, cacheSimpleConfigs);
    }

    private Set findCacheSimpleConfigAnnotation(AnnotationMetadata importingClassMetadata) {
        Set basePackages = getBasePackages(importingClassMetadata);
        ClassPathScanningCandidateComponentProvider scanner = getScanner();
        scanner.setResourceLoader(this.resourceLoader);
        scanner.addIncludeFilter(new MethodAnnotationTypeFilter(CacheSimpleConfig.class));
        Set cacheSimpleConfigs = new HashSet<>();
        for (String basePackage : basePackages) {
            Set candidateComponents = scanner
                    .findCandidateComponents(basePackage);
            for (BeanDefinition candidateComponent : candidateComponents) {
                if (candidateComponent instanceof AnnotatedBeanDefinition) {
                    AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
                    try {
                        Class target = ClassUtils.forName(
                                beanDefinition.getMetadata().getClassName(),
                                BindScannerRegistrar.this.classLoader);
                        Method[] methods = target.getMethods();
                        for (Method method : methods) {
                            CacheSimpleConfig annotation = ClassUtil.getAnnotation(method, CacheSimpleConfig.class);
                            if (annotation == null) {
                                continue;
                            }
                            cacheSimpleConfigs.add(annotation);

                        }
                    } catch (Exception ex) {
                        this.logger.error(
                                "Could not load target class: "
                                        + beanDefinition.getMetadata().getClassName(),
                                ex);
                    }
                }
            }
        }
        return cacheSimpleConfigs;
    }


    private void registerConfigCacheService(BeanDefinitionRegistry registry, Set cacheSimpleConfigs) {
        if (cacheSimpleConfigs.size() < 0) {
            return;
        }
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(AnnotationConfigCacheBuilder.class);
        builder.addConstructorArgValue(cacheSimpleConfigs);
        GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
        definition.setScope(BeanDefinition.SCOPE_SINGLETON);
        definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
        String beanId = org.apache.commons.lang3.StringUtils.uncapitalize(AnnotationConfigCacheBuilder.class.getSimpleName());
        registry.registerBeanDefinition(beanId, definition);
    }

    protected Set getBasePackages(AnnotationMetadata importingClassMetadata) {
        Map attributes = importingClassMetadata
                .getAnnotationAttributes(ComponentScan.class.getCanonicalName());
        Set basePackages = new HashSet<>();
        if (attributes != null) {
            for (String pkg : (String[]) attributes.get("basePackages")) {
                if (StringUtils.hasText(pkg)) {
                    basePackages.add(pkg);
                }
            }
        }
        return basePackages;
    }


    protected ClassPathScanningCandidateComponentProvider getScanner() {
        return new ClassPathScanningCandidateComponentProvider(false, this.environment) {
            @Override
            protected boolean isCandidateComponent(
                    AnnotatedBeanDefinition beanDefinition) {
                if (beanDefinition.getMetadata().isIndependent()) {
                    return true;
                }
                return false;
            }
        };
    }


    private class MethodAnnotationTypeFilter extends AnnotationTypeFilter {
        private final Class annotationType;

        public MethodAnnotationTypeFilter(Class annotationType) {
            super(annotationType);
            this.annotationType = annotationType;
        }


        @Override
        protected boolean matchSelf(MetadataReader metadataReader) {
            if (super.matchSelf(metadataReader)) {
                return true;
            }
            AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
            return metadata.getAnnotatedMethods(this.annotationType.getName()).size() > 0;
        }
    }

}





© 2015 - 2024 Weber Informatics LLC | Privacy Policy