com.github.bootfastconfig.cache.BindScannerRegistrar Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of boot-fast-config-cache Show documentation
Show all versions of boot-fast-config-cache Show documentation
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 extends Annotation> annotationType;
public MethodAnnotationTypeFilter(Class extends Annotation> 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;
}
}
}