自定义了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 "";
}
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(); } } }