http://blog.csdn.net/paincupid/article/details/50534412
自定义注解,结合AOP实现日志功能
在做AOP日志的的时候,注意:
<aop:aspectj-autoproxy proxy-target-class="true"/>
如果将上面的话放在spring-context.xml/applicationContext.xml中,这里的aop设置将不会生效!!
源代码下载地址:https://git.oschina.net/paincupid/springmvc.git
代码以下
[java] view plain copy 在CODE上查看代码片派生到我的代码片
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;
}
[java] view plain copy 在CODE上查看代码片派生到我的代码片
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 {}
}
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
别忘记引入:
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<?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">
使用:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
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);
}
}
自定义注解,结合AOP实现日志功能
在做AOP日志的的时候,注意:
<aop:aspectj-autoproxy proxy-target-class="true"/>
如果将上面的话放在spring-context.xml/applicationContext.xml中,这里的aop设置将不会生效!!
源代码下载地址:https://git.oschina.net/paincupid/springmvc.git
代码以下
[java] view plain copy 在CODE上查看代码片派生到我的代码片
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;
}
[java] view plain copy 在CODE上查看代码片派生到我的代码片
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 {}
}
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 -->
<aop:aspectj-autoproxy proxy-target-class="true" />
别忘记引入:
[html] view plain copy 在CODE上查看代码片派生到我的代码片
<?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">
使用:
[java] view plain copy 在CODE上查看代码片派生到我的代码片
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);
}
}