注解扫描工具

package com.test.scaner;

import static org.slf4j.LoggerFactory.getLogger;

import java.io.File;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;

import com.google.common.collect.Lists;

import eu.infomas.annotation.AnnotationDetector;
import eu.infomas.annotation.AnnotationDetector.Reporter;
import eu.infomas.annotation.AnnotationDetector.TypeReporter;


/**
 * 
 * Created by linjinzhi on 2016/11/18
 *
 */
public class AnnotationScanUtils {
	
	private static final Logger log = getLogger(AnnotationScanUtils.class);
	
	private AnnotationScanUtils(){}
	
	private static List<Class<?>> supportAnnotationClasses = new ArrayList<>();//特定注解作用下的类类型列表
	
	private static Map<Class<?>, Class<? extends Annotation>> classesMap = null;//类类型-注解类型映射
	
	
	/**
	 * 初始化列表和Map
	 * @param annotaionType 用户自定义注解类型.
	 * @param supportAnnotationPackage 注解作用下的类所在包
	 */
	private static void init(Class<? extends Annotation> annotaionType, String supportAnnotationPackage) {
		
		if(StringUtils.isNotBlank(supportAnnotationPackage)){
			
			String[] sitenameClazzArray = StringUtils.split(supportAnnotationPackage, ";");
            
            classesMap = scan(annotaionType, sitenameClazzArray);
 
            for(Entry<Class<?>, Class<? extends Annotation>> entry : classesMap.entrySet()) {
            	supportAnnotationClasses.add(entry.getKey());
            }
        }
	}
	
	
	/**
	 * 得到特定包下的特定注解作用的Class
	 * @param annotaionType 要求扫描的注解类型
	 * @param supportAnnotationPackage 扫描的包名称,如果有多个,则以';'分隔 
	 * @return 被特定注解作用且位于制定包下的所有具体类类型列表
	 */
	public static List<Class<?>> getSupportClasses(Class<? extends Annotation> annotaionType, String supportAnnotationPackage) {
		
		init(annotaionType, supportAnnotationPackage);
		
		return supportAnnotationClasses;
	}
	
	
	
	/**
	 * 得到类类型-注解类型映射
	 * @return
	 */
	public static Map<Class<?>, Class<? extends Annotation>> getObjectAnnotationMap(Class<? extends Annotation> annotaionType, String supportAnnotationPackage) {
		
		init(annotaionType, supportAnnotationPackage);
		
		return classesMap;
	}
	
	
	/**
     * 扫描类注解.
     *
     * @param annotationClass
     * @param packages
     * @return
     */
    private static Map<Class<?>, Class<? extends Annotation>> scan(
            final Class<? extends Annotation> annotationClass,
            String... packages) {
        final Map<Class<?>, Class<? extends Annotation>> classesMap = new HashMap<>();
        final Reporter reporter = new TypeReporter() {

            @SuppressWarnings("unchecked")
            @Override
            public Class<? extends Annotation>[] annotations() {
                return new Class[] { annotationClass };
            }

            @Override
            public void reportTypeAnnotation(
                    Class<? extends Annotation> annotation, String className) {
                try {
                    classesMap.put(Class.forName(className), annotation);
                } catch (ClassNotFoundException e) {
                    log.error("Class not found: {}", className, e);
                }
            }

        };
        startScan(reporter, packages);
        return classesMap;
    }
    
    
    private static void startScan(
            final AnnotationDetector.Reporter reporter, String... packageNames) {
        final AnnotationDetector cf = new AnnotationDetector(reporter);
        try {
            if (packageNames.length == 0) {
                // 解决在web容器下扫描不到类的问题.
                URL url = Thread.currentThread().getContextClassLoader()
                        .getResource("");
                File file = new File(url.getPath());
                File[] files = file.listFiles(
                        (File pathname) -> pathname.isDirectory() && !pathname.isHidden()
                );
                List<String> fileNames = Lists.newLinkedList();
                for (File one : files) {
                    fileNames.add(one.getName());
                }
                log.debug("san path:{}", fileNames);
                cf.detect(fileNames.toArray(new String[fileNames.size()]));
                // 这里扫描全部可能会有性能问题
                // XXX 在java项目中可以扫描到jar文件中的类,在web项目中不行.
                cf.detect();
            } else {
                cf.detect(packageNames);
            }
        } catch (IOException e) {
            log.error("scan package error packages:{}",
                    Arrays.toString(packageNames), e);
        }
    }
	
	
	/**
	 * test
	 * @param args
	 */
	public static void main(String[] args) {
		List<Class<?>> classes = AnnotationScanUtils.getSupportClasses(Crawler.class, "com.test.scaner;");
		for(Class<?> clazz : classes) {
			System.out.println(clazz);
		}
		
		Map<Class<?>, Class<? extends Annotation>> map = AnnotationScanUtils.getObjectAnnotationMap(Crawler.class, "com.test.scaner;");
		
		for(Entry<Class<?>, Class<? extends Annotation>> entry : map.entrySet()) {
			System.out.println(entry.getKey()+"\t"+entry.getValue());
		}
	}

}

 

转载于:https://my.oschina.net/ChiLin/blog/787950

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值