读取项目里带指定注解的方法

简介: 注解研究
package com.galaxy.mobile.api;

import com.galaxy.mobile.api.config.ApiAction;
import com.galaxy.mobile.common.utils.StringUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.FileFilter;
import java.lang.annotation.Annotation;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

/**
 * Created by fengyiming on 2016/7/18.
 */
public class MobileInterfaceStudyTest {

    private final static Logger logger = Logger.getLogger("myTest");

    public static void main(String[] args) {
        try{
            //扫描的包
            String packName = "com.galaxy.mobile.api.action";
            //jar包
            packName = "com.galaxy.image";
            logger.error("----packName:"+packName);
            //文件夹里所有类的集合
            List<Class<?>> classes = new ArrayList<Class<?>>();
            //扫描的包的路径
            String dirPath = packName.replaceAll("\\.", "/");
            //查找所有给定名称的资源
            Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader()
                    .getResources(dirPath);
            //是否需要递归遍历
            boolean isRecursive = true;
            //需要判定是否含有的注解
            Class<? extends Annotation> annotation = ApiAction.class;
            annotation = null;
            while (dirs.hasMoreElements()) {
                //获取该资源的URL
                URL url = dirs.nextElement();
                //判断该文件的文件类型
                String protocol = url.getProtocol();
                logger.error("----type:"+protocol);
                // 获取包的物理路径
                String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                if ("file".equals(protocol)) {
                    getClassList(classes, packName, filePath, isRecursive, annotation);
                }else if("jar".equals(protocol)){
                    getClassList(classes, packName, url,isRecursive, annotation);
                }
            }
            if(CollectionUtils.isNotEmpty(classes)){
                logger.error("-----classes all data start-----");
                for(int i=1;i<=classes.size();i++){
                    logger.error("---data " + i + "---" + classes.get(i - 1).getName());
                }
                logger.error("-----classes all data end-----");
            }
            logger.error("----the end-----");
        }catch (Exception e){
            logger.error("eee",e);
        }
    }

    /**
     * 获取包下所有的class类的集合
     * @param classList
     * @param packName
     * @param filePath
     * @param isRecursive
     */
    public static void getClassList(List<Class<?>> classList,String packName,String filePath,boolean isRecursive,Class<? extends Annotation> annotation){
        File[] files = fileFilterClass(filePath);
        logger.error("---filePath:"+filePath+",cout size:"+files.length);
        if(files != null) {
            for (File file:files) {
                if(file.isFile()){
                    logger.error("---fileName---" + file.getName());
                    String className = getClassName(packName, file.getName());
                    logger.error("----className :"+className);
                    addClass(classList, className, null);
                }else if(file.isDirectory()){
                    /** 以下不设置会导致实例化类的时候报错 */
                    //获取当前的包名称
                    String subPackName = packName+"."+file.getName();
                    //获取当前的包路径
                    String subPath = filePath+"/"+file.getName();
                    getClassList(classList,subPackName,subPath,isRecursive,annotation);
                }
            }
        }
    }

    public static void getClassList(List<Class<?>> classList,String packName,URL url,boolean isRecursive,Class<? extends Annotation> annotation){
        try{
            JarURLConnection jarURLConnection = (JarURLConnection)url.openConnection();
            JarFile jarFile = jarURLConnection.getJarFile();
            logger.error("----jar name:"+jarFile.getName());
            //此举会吧jar里所有的文件遍历出来
            Enumeration<JarEntry> jarEntries = jarFile.entries();
            while (jarEntries.hasMoreElements()){
                //jar里的每个文件对象(包括文件夹)
                JarEntry jarEntry = jarEntries.nextElement();
                String jarEntryName = jarEntry.getName();
                String classAllName = jarEntryName.replaceAll("/", "\\.");
                logger.error("----jar className"+classAllName);
                if(classAllName.endsWith(".class")){
                    int lastIndex = classAllName.lastIndexOf(".");
                    String className = classAllName.substring(0,lastIndex);
                    addClass(classList,className,annotation);
                }
            }
        }catch (Exception e){
            logger.error("---jar--error --",e);
        }
    }

    /**
     * 过滤class文件和文件夹
     * @param filePath
     * @return
     */
    private static File[] fileFilterClass(String filePath){
        if(StringUtils.isNullorBlank(filePath)){
            return null;
        }else{
            return new File(filePath).listFiles(new FileFilter() {
                @Override
                public boolean accept(File file) {
                    return ((file.isFile() && file.getName().endsWith(".class")) || file.isDirectory());
                }
            });
        }
    }

    /**
     * 获取class的类名和路径
     * @param path
     * @param fileName
     * @return
     */
    private static String getClassName(String path,String fileName){
        int lastIndex = fileName.lastIndexOf(".");
        if(lastIndex > 0){
            return path+"."+fileName.substring(0,lastIndex);
        }else{
            return "";
        }
    }

    private static void addClass(List<Class<?>> classList,String className,Class<? extends Annotation> annotation){
        if(!StringUtils.isNullorBlank(className)) {
            Class<?> classObject = null;
            try {
                classObject = Class.forName(className);
            } catch (ClassNotFoundException e) {
                logger.error("----class:" + className + "--cannot class.forname");
            }
            //类对象存在
            if(classObject != null) {
                //是否需要判断该类是否包含此注解
                if (annotation == null) {
                    classList.add(classObject);
                }else if(classObject.isAnnotationPresent(annotation)){
                    classList.add(classObject);
                }else{
                    logger.error("----class:" + className + "-not include--"+annotation.getName());
                }
            }
        }
    }
}
目录
相关文章
|
7月前
|
Java API Apache
使用AOP+反射实现Excel数据的读取
使用AOP+反射实现Excel数据的读取
|
2月前
|
存储 Java 数据库连接
@OneToOne注解的作用
@OneToOne注解的作用
|
7月前
|
存储 XML Java
Spring框架学习 -- 读取和存储Bean对象
Spring框架学习 -- 读取和存储Bean对象
53 0
Spring框架学习 -- 读取和存储Bean对象
|
存储 SQL Java
Java反射读取注解信息
Java反射读取注解信息
73 0
|
Java Spring
Spring项目中value注解,@Value不能a够读取到配置文件的值,无法成功注入值的问题解决(超简单)
Spring项目中value注解,@Value不能a够读取到配置文件的值,无法成功注入值的问题解决(超简单)
411 0
|
Java 编译器 测试技术
手写反射实现读取自定义注解中的属性值
手写反射实现读取自定义注解中的属性值
|
存储 设计模式 Java
Spring 更简单的读取和存储对象、使用注解存取对象
Spring 更简单的读取和存储对象、使用注解存取对象
|
存储 XML 设计模式
更方便Spring存储和读取对象,五大类注解、@Bean、@Autowired、@Resource
更方便Spring存储和读取对象,五大类注解、@Bean、@Autowired、@Resource
190 0
更方便Spring存储和读取对象,五大类注解、@Bean、@Autowired、@Resource
|
存储 XML Java
Spring【五大类注解的存储和读取Bean方法注解】(上)
Spring【五大类注解的存储和读取Bean方法注解】
Spring【五大类注解的存储和读取Bean方法注解】(上)
|
存储 设计模式 Java
Spring【五大类注解的存储和读取Bean方法注解】(下)
Spring【五大类注解的存储和读取Bean方法注解】(下)
Spring【五大类注解的存储和读取Bean方法注解】(下)