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