Spring Aop自定义注解实现日志管理
<?xml version="1.0" encoding="UTF-8"?> <!-- 查找最新的schemaLocation 访问 http://www.springframework.org/schema/ --> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd "> <!-- 最重要:::如果放在spring-context.xml中,这里的aop设置将不会生效 --> <aop:aspectj-autoproxy proxy-target-class="true"/> <!-- 启用MVC注解 --> <mvc:annotation-driven /> <!-- 指定Sping组件扫描的基本包路径 --> <context:component-scan base-package="com.bin.design"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> </beans>
package com.bin.design.annotation; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD}) //作用点:方法 @Retention(RetentionPolicy.RUNTIME) //什么时候生效:运行时 @Documented @Inherited public @interface LogController { String name() default ""; }
package com.bin.design.aop; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; import java.util.logging.Logger; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; 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.springframework.stereotype.Component; import com.alibaba.fastjson.JSON; import com.bin.design.exception.BusinessException; /** * 针对 Spring Aop 日志打印 * * @author HuangBin * */ @Aspect @Component public class LogAspect { private Logger logger = Logger.getLogger(this.getClass().getSimpleName()); @Pointcut("@annotation(com.bin.design.annotation.LogController)") public void log() { System.out.println("This is aop aspect!"); } /** * 目标执行前 * * @param joinPoint */ @Before("log()") public void beforeExcue(JoinPoint joinPoint) { Object[] parames = joinPoint.getArgs();// 目标方法体参数 logger.info(logMsgGet(joinPoint, ":start!", "params:", parseParames(parames))); } /** * 目标执行后 * * @param joinPoint */ @After("log()") public void afterExcue(JoinPoint joinPoint) { logger.info(logMsgGet(joinPoint, ":end!")); } /** * 目标成功执行后 * * @param joinPoint */ @AfterReturning(pointcut = "log()", returning = "returnValue") public void afterSuccess(JoinPoint joinPoint, Object returnValue) { logger.info(logMsgGet(joinPoint, ":end success!", "returnValue:", returnValue)); } /** * 目标产生异常时 */ @AfterThrowing(pointcut = "log()", throwing = "ex") public void addLog(JoinPoint joinPoint, BusinessException ex) { logger.info(logMsgGet(joinPoint, ":ERROR!", "Error Msg:", ex.getMessage())); } /** * 日志信息 * @param joinPoint * @param msg * @return */ private String logMsgGet(JoinPoint joinPoint, Object... msg) { Object object = joinPoint.getTarget(); MethodSignature ms = (MethodSignature) joinPoint.getSignature(); Method method = ms.getMethod(); StringBuilder builder = new StringBuilder(); builder.append("Class:").append(object.toString()).append("-->Method:").append(method.getName()); for (Object obj : msg) { if (obj != null){ if(obj instanceof String || isWrapClass(obj.getClass())){ builder.append(obj.toString()); }else{ builder.append(JSON.toJSONString(obj)); } } } return builder.toString(); } /** * 是否是基本类型 * @param clz void * @return */ private boolean isWrapClass(Class clz) { try { return ((Class) clz.getField("TYPE").get(null)).isPrimitive(); } catch (Exception e) { return false; } } /** * 是否是复合类型 * @param clz * @return */ private boolean isSy(Class clz){ return clz.isSynthetic(); } /** * 参数格式化 */ private String parseParames(Object[] parames) { if (parames == null || parames.length == 0) return null; StringBuilder builder = new StringBuilder(); for (Object obj : parames) { builder.append(JSON.toJSONString(obj)).append(","); } return builder.toString(); } private void prseMethod(Method method) { System.out.println("-------------getParameterAnnotations-----------------"); Annotation[][] annotations = method.getParameterAnnotations(); for (Annotation[] annotations2 : annotations) { for (Annotation annotation : annotations2) { System.out.println(annotation.toString()); } } System.out.println("-------------toGenericString-----------------"); System.out.println(method.toGenericString()); System.out.println("-------------getTypeParameters-----------------"); TypeVariable<Method>[] variables = method.getTypeParameters(); for (TypeVariable<Method> typeVariable : variables) { System.out.println(typeVariable.getName()); } System.out.println("-------------getGenericReturnType-----------------"); Type type = method.getGenericReturnType(); System.out.println(JSON.toJSON(type)); System.out.println("sy" + type.toString()); System.out.println("end prseMethod"); } }