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的主要内容,如果未能解决你的问题,请参考以下文章

springboot—spring aop 实现系统操作日志记录存储到数据库

spring框架

浅谈spring中AOP以及spring中AOP的注解方式

Spring框架学习笔记

spring注解开发及AOP

18spring注解学习(AOP)——AOP功能测试