SpringMVC利用AOP实现自定义注解记录日志

  • Post author:
  • Post category:其他





自定义注解,结合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);
	}
}




转载请注明:

http://blog.csdn.net/paincupid/article/details/50534412






版权声明:本文为paincupid原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。