文档章节

注解扫描工具

蜡笔小小小新
 蜡笔小小小新
发布于 2016/11/15 10:53
字数 522
阅读 54
收藏 1
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());
		}
	}

}

 

© 著作权归作者所有

上一篇: JedisTemplate
蜡笔小小小新
粉丝 33
博文 114
码字总数 75210
作品 0
深圳
后端工程师
私信 提问
Spring 开启Annotation 和 诠释及区别

和 的区别 是用于激活那些已经在spring容器里注册过的bean(无论是通过xml的方式还是通过package sanning的方式)上面的注解。 除了具有的功能之外,还可以在指定的pac...

ybyron
2016/10/27
0
0
Spring IoC基于注解的配置

Spring IoC基于注解的配置 Mz的博客2017-03-1872 阅读 SpringJava 定义Bean 我们知道,Spring容器启动成功需要三个条件:Bean定义信息,Bean实现类以及Spring本身。在采用XML配置时,Bean的定...

Mz的博客
2017/03/18
0
0
spring学习5-注解式bean配置+Junit简易使用

隔了两天,忙着面试,快累死了,终于有空来写博客了。好了,发完牢骚,进入我们今天的学习。 上篇spring学习4-bean配置文件中学习了使用xml配置文件配置bean,是不是觉得不淡定,每写一个类,...

大嘴吃鸡腿
2014/03/20
0
0
@SpringBootApplication 注解

@SpringBootApplication注解是一个组合注解,包含以下注解 @Target(ElementType.TYPE) 注解的作用目标 @Retention(RetentionPolicy.RUNTIME) Reteniton的作用是定义被它所注解的注解保留多久,...

java.刘
2018/08/19
0
0
12叔/abase-reader

#abase-reader 基于Abase android快速开发工具 基于 Fbreader 项目 界面参考ireader 不断更新中 #部署 请同时下载 Abase 项目加入到你的workspace 即可 打开eclipse注解编译开关 如图 关于注...

12叔
2014/04/29
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spring Boot 2 快速教程:WebFlux 集成 Mongodb(四)

摘要: 原创出处 https://www.bysocket.com 「公众号:泥瓦匠BYSocket 」欢迎关注和转载,保留摘要,谢谢! 这是泥瓦匠的第104篇原创 文章工程: * JDK 1.8 * Maven 3.5.2 * Spring Boot 2.1....

泥瓦匠BYSocket
27分钟前
2
0
$_ENV

$_ENV数组中的内容是在PHP解析器运行时,从PHP所在服务器中的环境变量, 导入到PHP的全局命名空间, 转变为PHP全局变量。 这些变量很多是由支持 PHP 运行的 Shell 提供的,并且不同的系统很可能...

vinci321
42分钟前
2
0
Guava RateLimiter + AOP注解实现单机限流、统计QPS

1、基于springboot项目pom.xml添加如下依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId></dependency><d......

铁骨铮铮
今天
3
0
JAVA NIO Connection reset by peer 异常

客户端主动断开与服务端的连接,但是如果客户端掉线,服务端就接收不到了。。 异常信息 java.io.IOException: Connection reset by peerat java.base/sun.nio.ch.FileDispatcherImpl.read...

Jeremy_pan
今天
2
0
龙芯版办公软件下载

金山wps office   rpm包:http://ftp.loongnix.org/os/loongnix/1.0/os/Packages/w/wps-office-10.8.0.6472-1.a20p1.mips64el.rpm   deb包:http://packages.deepin.com/loongson/pool/......

gugudu
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多