import com.huang.mapper.TestAnnotation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
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.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils;
import java.lang.annotation.Annotation;
import java.util.*;
/**
* @author a1
*/
public class SectionRegister implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
Logger LOG = LoggerFactory.getLogger(SectionRegister.class);
private static Map<String, TestAnnotation> SECTION_MAP = new HashMap<String, TestAnnotation>();
public void setSectionMap(Map<String, TestAnnotation> sectionMap) {
SECTION_MAP = sectionMap;
}
public Map<String, TestAnnotation> getSectionMap(){
return SECTION_MAP;
}
private ResourceLoader resourceLoader;
private ClassLoader classLoader;
private Environment environment;
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
logPackageScan(importingClassMetadata);
registerSections(importingClassMetadata, registry);
}
private void logPackageScan(AnnotationMetadata metadata) {
Map<String, Object> defaultAttrs = metadata.getAnnotationAttributes(SectionScan.class.getName(), true);
if (defaultAttrs != null && defaultAttrs.size() > 0) {
LOG.info("section package scan: " + buildPackages((String[]) defaultAttrs.get("basePackages")));
}
}
private String buildPackages(String[] basePackages) {
if (basePackages == null || basePackages.length == 0) {
return "null";
}
StringBuilder stringBuilder = new StringBuilder();
for (String s : basePackages) {
stringBuilder.append(s).append(",");
}
stringBuilder.substring(0, stringBuilder.length() - 2);
return stringBuilder.toString();
}
public void registerSections(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
ClassPathScanningCandidateComponentProvider scanner = getScanner();
scanner.setResourceLoader(this.resourceLoader);
Set<String> basePackages;
Map<String, Object> attrs = metadata.getAnnotationAttributes(SectionScan.class.getName());
AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(TestAnnotation.class);
scanner.addIncludeFilter(annotationTypeFilter);
basePackages = getBasePackages(metadata);
Map<String, TestAnnotation> sectionMap = new HashMap<String, TestAnnotation>();
for (String basePackage : basePackages) {
Set<BeanDefinition> candidates = new LinkedHashSet<BeanDefinition>();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
try {
// 这里特别注意一下类路径必须这样写
// 获取指定包下的所有类
basePackage = basePackage.replace(".", "/");
Resource[] resources = resourcePatternResolver.getResources( ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +basePackage+"**/*.class");
MetadataReaderFactory metadata1 = new SimpleMetadataReaderFactory();
for (Resource resource : resources) {
MetadataReader metadataReader = metadata1.getMetadataReader(resource);
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
candidates.add(sbd);
}
for (BeanDefinition beanDefinition : candidates) {
String classname = beanDefinition.getBeanClassName();
// 扫描Section注解
TestAnnotation s = Class.forName(classname).getAnnotation(TestAnnotation.class);
if (s != null) {
sectionMap.put(classname, s);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
//使用容器存储扫描出来的对象(类全限定名:section对象)
setSectionMap(sectionMap);
if(sectionMap!=null&§ionMap.size()>0){
RootBeanDefinition beanDefinition = new RootBeanDefinition(SectionRegister.class);
beanDefinition.setSynthetic(true);
registry.registerBeanDefinition("myAnnotation", beanDefinition);
}
}
protected ClassPathScanningCandidateComponentProvider getScanner() {
return new ClassPathScanningCandidateComponentProvider(false, this.environment) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
if (beanDefinition.getMetadata().isIndependent()) {
if (beanDefinition.getMetadata().isInterface()
&& beanDefinition.getMetadata().getInterfaceNames().length == 1
&& Annotation.class.getName().equals(beanDefinition.getMetadata().getInterfaceNames()[0])) {
try {
Class<?> target = ClassUtils.forName(beanDefinition.getMetadata().getClassName(),
SectionRegister.this.classLoader);
return !target.isAnnotation();
} catch (Exception ex) {
this.logger.error(
"Could not load target class: " + beanDefinition.getMetadata().getClassName(), ex);
}
}
return true;
}
return false;
}
};
}
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
Map<String, Object> attributes = importingClassMetadata
.getAnnotationAttributes(SectionScan.class.getCanonicalName());
Set<String> basePackages = new HashSet<String>();
for (String pkg : (String[]) attributes.get("basePackages")) {
if (pkg != null && !"".equals(pkg)) {
basePackages.add(pkg);
}
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(importingClassMetadata.getClassName()));
}
return basePackages;
}
}
注解类:
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.TYPE)
@Import({SectionRegister.class})
public @interface SectionScan {
String[] basePackages() default {};
}
切面类:
import com.huang.mapper.ss.SectionRegister;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
//声明这是一个组件
@Component
//声明这是一个切面Bean
@Aspect
@Slf4j
public class ServiceAspect {
@Autowired
Environment environment;
@Resource(name= "myAnnotation" )
SectionRegister myAnnotation;
@Pointcut("@within(com.huang.mapper.TestAnnotation)")
public void aspect() {
}
@Around(value = "aspect()")
public Object around(JoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
try {
log.info("around :" + joinPoint);
long end = System.currentTimeMillis();
String[] s = joinPoint.toString().split(" ");
log.info("property :" + s[0]+" sss2:"+s[1]);
System.out.println(s[1].substring(0,s[1].lastIndexOf(".")));
TestAnnotation testAnnotation = myAnnotation.getSectionMap().get(s[1].substring(0,s[1].lastIndexOf(".")));
System.out.println(testAnnotation.datasource());
String property = environment.getProperty(testAnnotation.datasource());
log.info("property :" + property);
log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms!");
} catch (Throwable e) {
long end = System.currentTimeMillis();
log.info("around " + joinPoint + "\tUse time : " + (end - start) + " ms with exception : " + e.getMessage());
throw e;
}
return null;
}
//配置后置返回通知,使用在方法aspect()上注册的切入点
@AfterReturning("aspect()")
public void afterReturn(JoinPoint joinPoint) {
log.info("afterReturn " + joinPoint);
}
//配置抛出异常后通知,使用在方法aspect()上注册的切入点
@AfterThrowing(pointcut = "aspect()", throwing = "ex")
public void afterThrow(JoinPoint joinPoint, Exception ex) {
log.info("afterThrow " + joinPoint + "\t" + ex.getMessage());
}
}
启动类
@SpringBootApplication()
@MapperScan(basePackages = "com.huang.mapper")
@SectionScan(basePackages={"com.huang.mapper"})
public class MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisApplication.class, args);
}
@Bean
public Map<String,String> getMyProperties(){
Map<String, String> objectObjectConcurrentHashMap = new ConcurrentHashMap<>();
return objectObjectConcurrentHashMap;
}
}
参考原地址:https://blog.csdn.net/congcongxianshen/article/details/100585037