自定义注解扫描方法

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&&sectionMap.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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值