Spring AOP 针对注解的AOP
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring AOP 针对注解的AOP相关的知识,希望对你有一定的参考价值。
我也忘记是从哪里扒来的代码,不过有了这个思路,以后可以自己针对 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; }
以上是关于Spring AOP 针对注解的AOP的主要内容,如果未能解决你的问题,请参考以下文章