我也忘记是从哪里扒来的代码,不过有了这个思路,以后可以自己针对 Controller 还有 Service层的任意 方法进行代理了
package pw.jonwinters.aop;
import java.lang.annotation.*; /**
*自定义注解 拦截Controller
*/ @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
String description() default "";
}
package pw.jonwinters.aop; 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; @Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemServiceLog {
String description() default "";
}
package pw.jonwinters.aop; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import pw.jonwinters.service.*;
@Aspect
@Component
public class SystemLogAspect {
@Autowired
@Qualifier("baseLogger")
private Logger log; @Pointcut("@annotation(pw.jonwinters.aop.SystemServiceLog)") //拦截带有此类注解的方法
public void serviceAspect() {
}
@Pointcut("@annotation(pw.jonwinters.aop.SystemControllerLog)")
public void controllerAspect() {
} @Before("controllerAspect()")
public void doBefore(JoinPoint joinPoint) throws Throwable { //joinPoint
log.info("aop is running!");
log.info("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
log.info("方法描述:" + getControllerMethodDescription(joinPoint)); //请求的IP
Thread.sleep(20000);
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getRemoteAddr();
try {
//*========控制台输出=========*//
log.info("=====前置通知开始=====");
log.info("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));
log.info("方法描述:" + getControllerMethodDescription(joinPoint));
log.info("请求IP:" + ip);
// Thread.sleep(2000);
}
finally{ }
} @AfterThrowing(pointcut = "serviceAspect()", throwing = "e")
public void doAfterThrowing(JoinPoint joinPoint, Throwable e) { } }
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {
String targetName = joinPoint.getTarget().getClass().getName(); //这是个工具类, 通过joinPoint对象 获得目标对象的引用 获得拦截对象的Class对象,然后获得Class对象的名称
String methodName = joinPoint.getSignature().getName(); //获得拦截方法的名称
Object[] arguments = joinPoint.getArgs(); //获得拦截方法的参数对象数组
Class<?> targetClass = Class.forName(targetName); //获得拦截对象的Class
Method[] methods = targetClass.getMethods(); //获得拦截对象的所有方法
String description = "";
for (Method method : methods) { //遍历方法
if (method.getName().equals(methodName)) { //当此方法的名称与拦截方法的名称相同时候
Class[] clazzs = method.getParameterTypes(); //获得这个方法的所有参数类型的 Class对象
if (clazzs.length == arguments.length) { //确保拦截的方法的参数个数 与 解析到的参数个数相同
description = method.getAnnotation(SystemControllerLog.class).description(); //然后获得方法的注解的description字段的值 并且返回
break;
}
}
}
return description;
}