SpringMVC利用AOP实现自定义注解记录日志
自定义注解,结合AOP实现日志功能
在做AOP日志的的时候,注意:
<aop:aspectj-autoproxy proxy-target-class="true"/>
如果将上面的话放在spring-context.xml/applicationContext.xml中,这里的aop设置将不会生效!!
源代码下载地址:https://git.oschina.net/paincupid/springmvc.git
代码以下
- package com.paincupid.springmvc.log;
- 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;
- @Retention(RetentionPolicy.RUNTIME)//注解会在class中存在,运行时可通过反射获取
- @Target(ElementType.METHOD)//目标是方法
- @Documented//文档生成时,该注解将被包含在javadoc中,可去掉
- public @interface OpLogger {
- public String id() default "-1";
- public enum OpType{ ADD,UPDATE, DEL, SEARCH};
- OpType type() default OpType.SEARCH;
- }
- package com.paincupid.springmvc.log;
- import java.lang.reflect.Method;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.Signature;
- import org.aspectj.lang.annotation.AfterReturning;
- import org.aspectj.lang.annotation.AfterThrowing;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Before;
- import org.aspectj.lang.annotation.Pointcut;
- import org.aspectj.lang.reflect.MethodSignature;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Component;
- import com.paincupid.springmvc.log.OpLogger.OpType;
- /**
- *
- * @author arthur.paincupid.lee
- * @since 2016.01.18
- */
- @Aspect
- @Component
- public class SysLogAspect {
- private static final Logger logger = LoggerFactory.getLogger(SysLogAspect. class);
- @Pointcut("@annotation(com.paincupid.springmvc.log.OpLogger)")
- public void controllerAspect() {
- }
- @Before("controllerAspect()")
- public void doBefore(JoinPoint joinPoint) {
- System.out.println("=====SysLogAspect前置通知开始=====");
- handleLog(joinPoint, null);
- }
- @AfterReturning(pointcut="controllerAspect()")
- public void doAfter(JoinPoint joinPoint) {
- System.out.println("=====SysLogAspect后置通知开始=====");
- handleLog(joinPoint,null);
- }
- @AfterThrowing(value="controllerAspect()",throwing="e")
- public void doAfter(JoinPoint joinPoint, Exception e) {
- System.out.println("=====SysLogAspect异常通知开始=====");
- handleLog(joinPoint, e);
- }
- private void handleLog(JoinPoint joinPoint,Exception e) {
- try {
- //获得注解
- OpLogger logger = giveController(joinPoint);
- if(logger == null)
- {
- return;
- }
- String signature = joinPoint.getSignature().toString(); // 获取目标方法签名
- String methodName = signature.substring(signature.lastIndexOf(".") + 1,
- signature.indexOf("("));
- String longTemp = joinPoint.getStaticPart().toLongString();
- String classType = joinPoint.getTarget().getClass().getName();
- Class<?> clazz = Class.forName(classType);
- Method[] methods = clazz.getDeclaredMethods();
- System.out.println("methodName: " + methodName);
- for (Method method : methods) {
- if (method.isAnnotationPresent(OpLogger.class)
- && method.getName().equals(methodName)) {
- //OpLogger logger = method.getAnnotation(OpLogger.class);
- String annId = logger.id();
- OpType type = logger.type();
- String clazzName = clazz.getName();
- System.out.println("clazzName: " + clazzName+ ", methodName: "
- + methodName + ", annId: "+ annId + ", type: "+type.toString());
- }
- }
- } catch (Exception exp) {
- logger.error("异常信息:{}", exp.getMessage());
- exp.printStackTrace();
- }
- }
- private static OpLogger giveController(JoinPoint joinPoint) throws Exception {
- Signature signature = joinPoint.getSignature();
- MethodSignature methodSignature = (MethodSignature) signature;
- Method method = methodSignature.getMethod();
- if (method != null) {
- return method.getAnnotation(OpLogger.class);
- }
- return null;
- }
- public void insertLogSuccess(JoinPoint jp, OpLogger logger) {}
- public void writeLogInfo(JoinPoint joinPoint, OpLogger opLogger)
- throws Exception, IllegalAccessException {}
- }
- <!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 -->
- <aop:aspectj-autoproxy proxy-target-class="true" />
别忘记引入:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans:beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
- xmlns:beans="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
- xmlns="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="
- http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
- "
- default-autowire="byName">
使用:
- package com.paincupid.springmvc.json.controller;
- import java.io.UnsupportedEncodingException;
- import java.util.List;
- import org.apache.ibatis.builder.ParameterExpression;
- import org.aspectj.lang.JoinPoint;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.stereotype.Controller;
- import org.springframework.ui.Model;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.bind.annotation.RequestMethod;
- import org.springframework.web.bind.annotation.RequestParam;
- import org.springframework.web.bind.annotation.ResponseBody;
- import com.paincupid.springmvc.log.OpLogger;
- import com.paincupid.springmvc.log.OpLogger.OpType;
- import com.paincupid.springmvc.test.domain.Person;
- import com.paincupid.springmvc.util.BaseJsonRst;
- import com.paincupid.springmvc.util.CreatMockData;
- @Controller
- @RequestMapping("/jqueryFormPluginSimple")
- public class JqueryFormPluginSimpleController {
- private static final Logger log = LoggerFactory.getLogger(JqueryFormPluginSimpleController.class);
- /**
- * 在前台的访问路径为: http://localhost:8080/springmvc/jqueryFormPluginSimple/list
- * @param person
- * @param model
- * @return
- */
- @RequestMapping("/list")
- @OpLogger(id = "18611112222", type=OpType.SEARCH)
- public String listPerson() {
- return "json/jqueryFormPluginSimple";
- }
- /**
- * 请求接收的是一个Java类
- * @param person
- * @return
- */
- @ResponseBody
- @OpLogger(id = "18633334444", type=OpType.SEARCH)
- @RequestMapping(value="/getForm", method=RequestMethod.POST)
- public BaseJsonRst<List<Person>> getForm(Person person, @RequestParam("currentPage") int currentPage){
- log.info("\r\nid: "+person.getId()+", name: "+person.getName()+", currentPage: "+currentPage);
- BaseJsonRst<List<Person>> ret = new BaseJsonRst<List<Person>>();
- List<Person> list = CreatMockData.createPersonList(20,currentPage);
- ret.setResult(list);
- ret.setTotalCounts(250);
- ret.setCurrentPage(person.getCurrentPage());
- ret.setSuccess(true);
- /**
- * 如果抛出异常,刚可以被日志捕获到,但如果是try catch的话,就不得调到public void doAfter(JoinPoint joinPoint, Exception e) 方法了
- */
- //throw Exception("error happen!");
- return ret;
- }
- private Exception Exception(String string) {
- // TODO Auto-generated method stub
- return null;
- }
- public static void main(String[] args){
- int a = (int)Math.ceil(1.002);
- System.out.println(a);
- }
- }