java获取包下面的自定义注解

自定义了Controller和RequestMapping两个注解,先去扫描加了@Controller注解的类,接着扫描这些类下面加了@RequestMapping注解的方法,然后通过java的反射invoke方法去调用加了RequestMapping注解的方法。

(1)该工程的目录结构如下

完整的工程代码下载链接如下:https://github.com/HelloKittyNII/JavaCustomAnnotation

(2)annotation包下面自定义了两个注解。

Controller.java

package com.huawi.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by wzj on 2016/10/1.
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller
{
    String value() default "";
}
package com.huawi.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Created by wzj on 2016/10/1.
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping
{
    String value() default "";
}


(3)bean包下面定义了一个存放RequestMapping注解方法的对象

ExecutorBean.java

package com.huawi.bean;

import java.lang.reflect.Method;
import java.util.Objects;

/**
 * Created by wzj on 2016/10/1.
 */
public class ExecutorBean
{
    private Object object;

    private Method method;

    public Object getObject()
    {
        return object;
    }

    public void setObject(Object object)
    {
        this.object = object;
    }

    public Method getMethod()
    {
        return method;
    }

    public void setMethod(Method method)
    {
        this.method = method;
    }
}

(4)controller包下面定义了几个类,其中有两个类使用了自定义的Controller注解

CatController.java

package com.huawi.controller;

import com.huawi.annotation.Controller;
import com.huawi.annotation.RequestMapping;

/**
 * Created by wzj on 2016/10/1.
 */
@Controller
public class CatController
{
    @RequestMapping(value = "/test1")
    public void test1()
    {
        System.out.println("CatController->test1()");
    }

    @RequestMapping(value = "/test2")
    public void test2()
    {
        System.out.println("CatController->test2()");
    }
}

DogController.java
package com.huawi.controller;

import com.huawi.annotation.Controller;
import com.huawi.annotation.RequestMapping;

/**
 * Created by wzj on 2016/10/1.
 */
@Controller
public class DogController
{
    @RequestMapping(value = "/test3")
    public void test3()
    {
        System.out.println("DogController->test3()");
    }

    @RequestMapping(value = "/test4")
    public void test4()
    {
        System.out.println("DogController->test4()");
    }
}

Rabbit.java
package com.huawi.controller;

import com.huawi.annotation.RequestMapping;

/**
 * Created by wzj on 2016/10/5.
 */
public class Rabbit
{
    @RequestMapping
    public void test1()
    {
        System.out.println("Rabbit->test1()");
    }
}

(5)util包下面定义了一个工具类,来对包进行扫描获取自定义注解的类和方法
AnnoManageUtil.java
package com.huawi.util;

import com.huawi.annotation.RequestMapping;
import com.huawi.bean.ExecutorBean;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.lang.annotation.Annotation;
//import java.lang.reflect.Method;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

/**
 * Created by wzj on 2016/10/1.
 */
public final class AnnoManageUtil
{
    /**
     * 获取当前包路径下指定的Controller注解类型的文件
     * @param packageName 包名
     * @param annotation 注解类型
     * @return 文件
     */
    public static  List<Class<?>> getPackageController(String packageName, Class<? extends Annotation> annotation)
    {
        List<Class<?>> classList = new ArrayList<Class<?>>();

        String packageDirName = packageName.replace('.', '/');

        Enumeration<URL> dirs = null;

        //获取当前目录下面的所有的子目录的url
        try
        {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        while (dirs.hasMoreElements())
        {
            URL url = dirs.nextElement();

            //得到但钱url的类型
            String protocol = url.getProtocol();

            //如果当前类型是文件类型
            if ("file".equals(protocol))
            {
                //获取包的物理路径
                String filePath = null;
                try
                {
                    filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                }
                catch (UnsupportedEncodingException e)
                {
                    e.printStackTrace();
                }

                filePath = filePath.substring(1);
                getFilePathClasses(packageName,filePath,classList,annotation);
            }
        }


            return classList;
    }

    /**
     * 从指定的包下面找到文件名
     * @param packageName
     * @param filePath
     * @param classList
     * @param annotation 注解类型
     */
    private static void getFilePathClasses(String packageName,String filePath,List<Class<?>> classList,
                                           Class<? extends Annotation> annotation)
    {
        Path dir = Paths.get(filePath);

        DirectoryStream<Path> stream = null;
        try
        {
            //获得当前目录下的文件的stream流
            stream = Files.newDirectoryStream(dir);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }

        for(Path path : stream)
        {
            String fileName = String.valueOf(path.getFileName());

            String className = fileName.substring(0, fileName.length() - 6);

            Class<?> classes = null;
            try
            {
                classes = Thread.currentThread().getContextClassLoader().loadClass(packageName + "." + className);
            }
            catch (ClassNotFoundException e)
            {
                e.printStackTrace();
            }

            //判断该注解类型是不是所需要的类型
            if (null != classes && null != classes.getAnnotation(annotation))
            {
                //把这个文件加入classlist中
                classList.add(classes);
            }
        }
    }

    /**
     * 获取classList下面的RequestMapping方法保存在mapp中
     * @param classList 保存加了Controller的类
     * @param mapp  存放url和ExecutorBean的对应关系
     */
    public static void getRequestMappingMethod(List<Class<?>> classList, Map<String,ExecutorBean> mapp)
    {
        for (Class classes : classList)
        {
            //得到该类下面的所有方法
            Method[] methods = classes.getDeclaredMethods();

            for (Method method : methods)
            {
                //得到该类下面的RequestMapping注解
                RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
                if (null != requestMapping)
                {
                    ExecutorBean executorBean = new ExecutorBean();
                    try
                    {
                        executorBean.setObject(classes.newInstance());
                    }
                    catch (InstantiationException e)
                    {
                        e.printStackTrace();
                    }
                    catch (IllegalAccessException e)
                    {
                        e.printStackTrace();
                    }

                    executorBean.setMethod(method);

                    mapp.put(requestMapping.value(),executorBean);

                }
            }
        }
    }




}

(6)test包下面是一个测试的类
main.java
package com.huawi.test;

import com.huawi.annotation.Controller;
import com.huawi.bean.ExecutorBean;
import com.huawi.util.AnnoManageUtil;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class Main {

    public static void main(String[] args)
    {
        List<Class<?>> classesList = null;
        classesList = AnnoManageUtil.getPackageController("com.huawi.controller",Controller.class);

        Map<String,ExecutorBean> mmap = new HashMap<String,ExecutorBean>();

        AnnoManageUtil.getRequestMappingMethod(classesList,mmap);

        ExecutorBean bean = mmap.get("/test1");
        try {
            bean.getMethod().invoke(bean.getObject());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dmfrm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值