自定义注解的用法, 好多人不知道, 在这里, 代码的注释中, 我已经详细的介绍了,
另外就是很多人不知道自定义注解如何使用, 这里配合springMVC拦截器, 做一个非常实用的案例.
案例: 记录系统操作的日志
首先是定义注解:
package cn.wxy.ssm.myAnnotation;
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;
/**
* @author wxy E-mail:wxypersonal@163.com
* @date 创建时间:2017年5月25日 下午5:05:22
* @version 1.0版本
* @company xxx科技公司
* @description 描述: 自定义注解: 这个注解是用在某一个成员方法上, 标识这个方法具体是增删改查具体什么内容
* */
@Target(ElementType.METHOD) //表明该注解对成员方法起作用
@Retention(RetentionPolicy.RUNTIME) //在编译以后仍然起作用
@Documented //支持JavaDoc文档注释
public @interface record {
String actionType() default "默认动作类型"; //一般有增加, 删除, 修改, 查询
String businessLogic() default "默认业务逻辑";
}
然后, 在一个普通的ssm框架中来只用它, 新建一个web层的controller类:
package cn.wxy.ssm.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.wxy.ssm.myAnnotation.record;
/**
* @author wxy E-mail:wxypersonal@163.com
* @date 创建时间:2017年5月25日 下午8:19:17
* @version 1.0版本
* @company xxx科技公司
* @description 描述: 测试自定义注解的controller层类
* */
@Controller
public class TestAnnotationController extends BaseController {
@RequestMapping(value = "wxy/testAnnotation.action")
@record(actionType = "测试, 没有做任何后台增删改",businessLogic="测试好不好使")
public String test(){
System.out.println("执行完这行代码, 执行拦截器");
return "success";
}
}
此时, 我们需要在springmvc的xml配置文件中, 来构建拦截器, 拦截上面的controller
<!-- 配置拦截器, -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/> <!-- 具体匹配原则可以百度
/**的意思是所有文件夹及里面的子文件夹
/*是所有文件夹,不含子文件夹
/是web项目的根目录
-->
<bean class="cn.wxy.ssm.interceptor.OperationLogInteceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
创建上面配置的拦截器, 来继承HandlerInteceptorAdaptor 或者实现 HandlerInteceptor 接口. 个人比较推荐前者.
package cn.wxy.ssm.interceptor;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import cn.wxy.ssm.myAnnotation.record;
/**
* @author wxy E-mail:wxypersonal@163.com
* @date 创建时间:2017年5月25日 下午3:49:55
* @version 1.0版本
* @company xxx科技公司
* @description 描述: 继承HandlerInterceptorAdapter, 重写里面的方法
* */
public class OperationLogInteceptor extends HandlerInterceptorAdapter {
/* (non-Javadoc)
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#preHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
* 预处理, 进行代码编写, 安全控制等.
*/
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
System.out.println("进入方法之前进行拦截");
return super.preHandle(request, response, handler);
}
/* (non-Javadoc)
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#postHandle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, org.springframework.web.servlet.ModelAndView)
* 返回处理, 这里有机会修改ModelAndView
*/
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
//wxy笔记: 现在我要在这里做的事情是: 添加日志, 记录进行的操作. 日志的内容来源于我在
// 操作的方法中添加的 自定义注解, 因为自定义注解中有参数, 这些参数记录的是操作的主要内容
// 我只要在这里用反射将方法上自定义注解的内容拿出来, 添加到日志里面就行了/
System.out.println("拦截器执行.......");
HandlerMethod hm = (HandlerMethod) handler;//将其强转过来
record record = hm.getMethodAnnotation(record.class);//拿到里面的自定义注解对象//通过反射
if (record != null) {
//Map<String, String[]> params = request.getParameterMap();
//对params这个map集合的键进行遍历
//Set<String> paramsKey = params.keySet();
//Iterator<String> it = paramsKey.iterator();
/*while (it.hasNext()) {
String key = (String) it.next();
}*/
String actionType = record.actionType();//拿到自定义注解中的字段值 动作类型
String businessLogic = record.businessLogic();//拿到自定义注解中的字段值 业务逻辑
String str = "动作类型是:" + actionType + " 业务逻辑是:" + businessLogic;
//执行日志记录
saveLog(str);
}
super.postHandle(request, response, handler, modelAndView);
}
/**
* 进行日志记录, 日志一般分两种:一种是数据库(系统操作日志),一种是写入磁盘(系统运行日志 log4j这类)
* 这里我们这是属于系统操作日志, 需要存入数据库, 但是为了演示, 这里只打印到控制台.
* @param str
*/
private void saveLog(String str) {
try {
System.out.println(str);
//真正开发中, 这里传递日志到数据库, 操作失败在catch中添加系统运行日志
} catch (Exception e) {
e.printStackTrace();
}
}
/* (non-Javadoc)
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterCompletion(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object, java.lang.Exception)
* 后处理, 可以根据ex是否为null判断是否发生了异常,进行日志记录。
*/
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
super.afterCompletion(request, response, handler, ex);
}
/* (non-Javadoc)
*
* @see org.springframework.web.servlet.handler.HandlerInterceptorAdapter#afterConcurrentHandlingStarted(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, java.lang.Object)
* 这个这里不做研究暂时.
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
// TODO Auto-generated method stub
super.afterConcurrentHandlingStarted(request, response, handler);
}
}
最后我们来执行测试: 直接访问即可:
http://localhost:8080/wxySSM/wxy/testAnnotation.action 查看你们的Tomcat是否是8080, 另外, wxySSM 是项目名.
最后我把我创建的这个项目目录结构截图给大家参考, 以便更清晰学习.