java注解的使用

java

资料:

(1)注解Annotation实现原理与自定义注解例子:

https://www.cnblogs.com/acm-bingzi/p/javaAnnotation.html

我的:

步骤一:自定义注解

/src/com/test/annotation/Controller.java

package com.test.annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target(ElementType.TYPE)//表示该自定义注解作用于类

@Retention(RetentionPolicy.RUNTIME)//表示运行期也保留该自定义注解,因此可以使用反射机制读取该注解的信息

@Documented//表示是否将注解信息添加在java文档中

public @interface Controller {}

/src/com/test/annotation/RequestMapping.java

package com.test.annotation;

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})//表示该自定义注解作用于类和方法

@Retention(RetentionPolicy.RUNTIME)//表示运行期也保留该自定义注解,因此可以使用反射机制读取该注解的信息

@Documented//表示是否将注解信息添加在java文档中

public @interface RequestMapping {

//映射名

String name() default "";

//路径名集合

String value() default "";//参数成员只能用byte,short,char,int,long,float,double,boolean八种基本数据类型和String、Enum、Class、annotations等数据类型,以及这一些类型的数组

//提交方式集合

RequestMethod method() default RequestMethod.GET;

}

/src/com/test/annotation/RequestMethod.java

package com.test.annotation;

public enum RequestMethod {

GET,

POST,

PUT,

DELETE;

}

步骤二:注解处理类

/src/com/test/annotation/ClassUtil.java

package com.test.annotation;

import java.io.File;

import java.io.FileFilter;

import java.io.IOException;

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;

public class ClassUtil {

/**

* 通过包名获取包内所有类

*

* @param pkg

* @return

*/

public static List<Class<?>> getAllClassByPackageName(Package pkg) {

String packageName = pkg.getName();

// 获取当前包下以及子包下所以的类

List<Class<?>> returnClassList = getClasses(packageName);

return returnClassList;

}

/**

* 通过接口名取得某个接口下所有实现这个接口的类

*/

public static List<Class<?>> getAllClassByInterface(Class<?> c) {

List<Class<?>> returnClassList = null;

if (c.isInterface()) {

// 获取当前的包名

String packageName = c.getPackage().getName();

// 获取当前包下以及子包下所以的类

List<Class<?>> allClass = getClasses(packageName);

if (allClass != null) {

returnClassList = new ArrayList<Class<?>>();

for (Class<?> cls : allClass) {

// 判断是否是同一个接口

if (c.isAssignableFrom(cls)) {

// 本身不加入进去

if (!c.equals(cls)) {

returnClassList.add(cls);

}

}

}

}

}

return returnClassList;

}

/**

* 取得某一类所在包的所有类名 不含迭代

*/

public static String[] getPackageAllClassName(String classLocation, String packageName) {

// 将packageName分解

String[] packagePathSplit = packageName.split("[.]");

String realClassLocation = classLocation;

int packageLength = packagePathSplit.length;

for (int i = 0; i < packageLength; i++) {

realClassLocation = realClassLocation + File.separator + packagePathSplit[i];

}

File packeageDir = new File(realClassLocation);

if (packeageDir.isDirectory()) {

String[] allClassName = packeageDir.list();

return allClassName;

}

return null;

}

/**

* 从包package中获取所有的Class

*

* @param pack

* @return

*/

public static List<Class<?>> getClasses(String packageName) {

// 第一个class类的集合

List<Class<?>> classes = new ArrayList<Class<?>>();

// 是否循环迭代

boolean recursive = true;

// 获取包的名字 并进行替换

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

// 定义一个枚举的集合 并进行循环来处理这个目录下的things

Enumeration<URL> dirs;

try {

dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);

// 循环迭代下去

while (dirs.hasMoreElements()) {

// 获取下一个元素

URL url = dirs.nextElement();

// 得到协议的名称

String protocol = url.getProtocol();

// 如果是以文件的形式保存在服务器上

if ("file".equals(protocol)) {

// 获取包的物理路径

String filePath = URLDecoder.decode(url.getFile(), "UTF-8");

// 以文件的方式扫描整个包下的文件 并添加到集合中

findAndAddClassesInPackageByFile(packageName, filePath, recursive, classes);

} else if ("jar".equals(protocol)) {

// 如果是jar包文件

// 定义一个JarFile

JarFile jar;

try {

// 获取jar

jar = ((JarURLConnection) url.openConnection()).getJarFile();

// 从此jar包 得到一个枚举类

Enumeration<JarEntry> entries = jar.entries();

// 同样的进行循环迭代

while (entries.hasMoreElements()) {

// 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件

JarEntry entry = entries.nextElement();

String name = entry.getName();

// 如果是以/开头的

if (name.charAt(0) == \'/\') {

// 获取后面的字符串

name = name.substring(1);

}

// 如果前半部分和定义的包名相同

if (name.startsWith(packageDirName)) {

int idx = name.lastIndexOf(\'/\');

// 如果以"/"结尾 是一个包

if (idx != -1) {

// 获取包名 把"/"替换成"."

packageName = name.substring(0, idx).replace(\'/\', \'.\');

}

// 如果可以迭代下去 并且是一个包

if ((idx != -1) || recursive) {

// 如果是一个.class文件 而且不是目录

if (name.endsWith(".class") && !entry.isDirectory()) {

// 去掉后面的".class" 获取真正的类名

String className = name.substring(packageName.length() + 1, name.length() - 6);

try {

// 添加到classes

classes.add(Class.forName(packageName + \'.\' + className));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

}

}

} catch (IOException e) {

e.printStackTrace();

}

return classes;

}

/**

* 以文件的形式来获取包下的所有Class

*

* @param packageName

* @param packagePath

* @param recursive

* @param classes

*/

private static void findAndAddClassesInPackageByFile(String packageName, String packagePath, final boolean recursive, List<Class<?>> classes) {

// 获取此包的目录 建立一个File

File dir = new File(packagePath);

// 如果不存在或者 也不是目录就直接返回

if (!dir.exists() || !dir.isDirectory()) {

return;

}

// 如果存在 就获取包下的所有文件 包括目录

File[] dirfiles = dir.listFiles(new FileFilter() {

// 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)

public boolean accept(File file) {

return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));

}

});

// 循环所有文件

for (File file : dirfiles) {

// 如果是目录 则继续扫描

if (file.isDirectory()) {

findAndAddClassesInPackageByFile(packageName + "." + file.getName(), file.getAbsolutePath(), recursive, classes);

} else {

// 如果是java类文件 去掉后面的.class 只留下类名

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

try {

// 添加到集合中去

classes.add(Class.forName(packageName + \'.\' + className));

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

}

}

Action封装类

/src/com/test/annotation/MyAction.java

package com.test.annotation;

import java.lang.reflect.Method;

public class MyAction {

private String path;//路径

private RequestMethod requestMethod;//提交方式

private Class<?> clazz;//类

private Method method;//方法

public MyAction(String path,RequestMethod requestMethod,Class<?> clazz,Method method){

this.path = path;

this.requestMethod = requestMethod;

this.clazz = clazz;

this.method = method;

}

@Override

public String toString() {

return "MyAction {\"path\":" + path + ", \"requestMethod\":" + requestMethod

+ ", \"clazz\":" + clazz + ", \"method\":" + method + "}";

}

//setter和getter

}

注解处理器

/src/com/test/annotation/ActionsUtil.java

package com.test.annotation;

import java.lang.reflect.Method;

import java.util.ArrayList;

import java.util.List;

/*

* 注解处理器

*/

public class ActionsUtil {

//Controller注解类

private static final Class<Controller> CONTROLLER = Controller.class;

//RequestMapping注解类

private static final Class<RequestMapping> REQUEST_MAPPING = RequestMapping.class;

//映射集合

private static List<MyAction> actionList=new ArrayList<MyAction>();

/**获取某个包下的所有控制器的所有action*/

public static List<MyAction> getActionsByPackageName(String packageName){

List<Class<?>> clazzs = ClassUtil.getClasses(packageName);

//遍历

for(Class<?> clazz:clazzs){

/**判断 该类 是否被Controller注解标记,如果没有,继续下一个*/

if(!clazz.isAnnotationPresent(CONTROLLER)){

continue;

}

/**获取某个控制器的所有action*/

setActionsListByClazz(clazz);

}

return actionList;

}

/**获取某个控制器的所有action*/

private static void setActionsListByClazz(Class<?> clazz){

/**判断 该类 是否被RequestMapping注解标记,如果有,则获取注解值作为 路径前缀*/

String pathPre = "";

if(clazz.isAnnotationPresent(REQUEST_MAPPING)){

//如果有,则获取注解值

RequestMapping mapping = clazz.getAnnotation(REQUEST_MAPPING);

pathPre = mapping.value();

pathPre =((\'/\'==pathPre.charAt(0))?pathPre:("/"+pathPre));

}

/**获取 类 的 方法 集合*/

Method[] ms = clazz.getDeclaredMethods();

for(Method m:ms){

//判断 该方法 是否被RequestMapping注解标记

//如果有,则获取注解对象,并拼接path

if (m.isAnnotationPresent(REQUEST_MAPPING)) {

RequestMapping mapping = m.getAnnotation(REQUEST_MAPPING);

String value = mapping.value();

//如果value为空字符串或null,则继续下一个方法

if("".equals(value)||null==value){

continue;

}

//----获取方法的参数名、参数类型

//----Map<String,Class<?>> params =new HashMap<String,Class<?>>();

//----m.getParameterAnnotations()

//----留待以后做

String path = pathPre + "/" + ((\'/\'==value.charAt(0))?(value.substring(1)):value);

//创建一个MyAction对象

MyAction action = new MyAction(path,mapping.method(),clazz,m);

actionList.add(action);

}

}

}

//处理请求

public static Object HandleRequest(Class<?> clazz,Method method,String jsonParam) throws Exception{

//利用反射调用某控制器的某方法

Object obj = clazz.newInstance();

return method.invoke(obj, jsonParam);

}

}

步骤三:模拟springmvc的请求调度类

/src/com/test/controller/UserController.java

package com.test.controller;

import com.test.annotation.Controller;

import com.test.annotation.RequestMapping;

import com.test.annotation.RequestMethod;

@Controller

@RequestMapping("user")

public class UserController {

@RequestMapping(value="login",method=RequestMethod.GET)

public String login(){

return "hello";

}

@RequestMapping(value="register",method=RequestMethod.GET)

public String register(){

return "hello";

}

}

/src/com/test/dispatcher/HandlerServlet.java

package com.test.dispatcher;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.List;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import com.test.annotation.ActionsUtil;

import com.test.annotation.MyAction;

//模拟springMvc的请求调度器

@WebServlet("/")

public class HandlerServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

/**调用ActionsUtil工具获取actions*/

private static List<MyAction> actions = null;

public HandlerServlet() {

super();

/**调用ActionsUtil工具获取并初始化actions*/

actions =ActionsUtil.getActionsByPackageName("com.test.controller");

}

@Override

protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

try{

//获取method

String method = request.getMethod();

//获取path

String path = request.getServletPath();

System.out.println(path);

if(path.endsWith(".html")||path.endsWith(".jsp")){

response.setStatus(200);

response.setCharacterEncoding("utf8");//指定字符编码

PrintWriter out = response.getWriter();//编写页面

out.println("<html><head><title>你好,你使用的是请求调度</title></head><body>你好,你使用的是请求调度</body></html>");

out.flush();

out.close();

}else{

//遍历action

for(int i=0;i<actions.size();i++){

MyAction action = actions.get(i);

//判断路径、提交方法 是否匹配

if(path.trim().equals("/service"+action.getPath().trim())&&method.trim().equals(action.getRequestMethod().toString())){

//利用反射执行某控制器的某方法

String jsonParam = request.getParameter("jsonParam");

//利用反射调用某控制器的某方法

Object obj = action.getClazz().newInstance();

try{

String target = null;

//如果参数为空

if(null==jsonParam){

target = (String) action.getMethod().invoke(obj);

}else{

target = (String) action.getMethod().invoke(obj, jsonParam);

}

//如果参数匹配,则响应为200

response.setStatus(200);

request.getRequestDispatcher(target+".html").forward(request, response);

}catch(Exception e){

//如果参数不匹配,则响应为400

response.setStatus(400);

}

}else{

//如果路径不匹配,则响应为404

response.setStatus(404);

}

}

}

}catch(Exception e){

e.printStackTrace();

//返回500

}

}

}

 

以上是 java注解的使用 的全部内容, 来源链接: utcz.com/z/394890.html

回到顶部