spring实现自定义注解且使用AOP做日志切入

在spring中,我们可以看到各种各样的注解,例

一、为什么要使用自定义注解

在spring中,我们可以看到各种各样的注解,例如常见的component、controller、service、repository等等。这些注解最大的作用就是标识某个类或某个方法是否交给spring去管理,那么当我们想要对我们自己的类或方法进去某些标识的时候,就可以用到自定义注解。我比较常用到自定义注解的情景如:利用AOP做切面,切日志切权限的时候,往往需要一个标识却判断哪些需要加日志,哪些接口是拥有什么样的权限才能访问等等。

二、如何实现自定义注解

简单讲一下,一般注解就像一般的类只不过public class 换成了 public @interface ,然后头上一般会有两个注解,一个是Target(),这个目标对象,也就是说要对什么类型的起作用,如ElementType.METHOD即对方法起效,也就是这个注解只能用在方法上,还有加在类上的,自己有兴趣可以了解一下。@Retention即注解的生命周期,也就是注解能存活到什么时候。source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在。然后详细代码如下,很简单,基本上有点基础的小伙伴都能看懂,有疑问可以底部留言!

package com.pratice.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * Demo class
 *
 * @author Pine and cypress
 * @date 2021/10/26
 */
@Target({
    
     ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
    
    

    String  content();



}

三、使用AOP配置日志切面

最后写一个自定义注解的应用场景-----AOP做日志切面,AOP是spring的核心之一,有了解spring的小伙伴应该都清楚,不了解的小伙伴也可以百度一下,AOP也算是spring中的一大块,我几句话也说不清,后续有时间会出一期关于AOP的详细讲解,这里不多做陈述。首先可以pointcut切点和Before或者AfterRuring分开写,也可以如第二段代码一样合起来一起写,直接在环绕通知@Around(“execution(* com.pratice.controller..(…))”)里写上要切入的地方,如这里就是在进入到 com.pratice下所有的controller前都要进行日志记录。

package com.pratice.aop;


import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class AOPLog {
    
    

    private long start = 0;

    @Pointcut("execution(* com.pratice.controller.*.*(..))")
    public  void  haha(){
    
    }

    @Before("haha()")
    public  void  before(JoinPoint point){
    
    
        ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = requestAttributes.getRequest();
        HttpServletResponse response = requestAttributes.getResponse();

        String addr = request.getRemoteAddr();
        String uri = request.getRequestURI();
        Object[] args = point.getArgs();

        start = System.currentTimeMillis();
        log.info("===================请求的地址是:================="+addr);
        log.info("===================请求的路径是:================="+uri);
        log.info("===================请求的参数是:================="+ Arrays.toString(args));

    }

    @AfterReturning("haha()")
    public  void  after(){
    
    
        long end = System.currentTimeMillis();
        log.info("=================耗时================="+ (end-start));
        log.info("=================结束了=================");
    }

}

package com.pratice.aop;

import com.pratice.annotation.MyLog;
import com.pratice.dao.SysOperationLogDao;
import com.pratice.entity.SysEmpInfo;
import com.pratice.entity.SysOperationLog;
import com.pratice.result.Result;
import com.pratice.util.ShiroUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;

@Component
@Aspect
public class OperationLog {
    
    
    


    @Around("execution(* com.pratice.controller.*.*(..))")
    public Result after(ProceedingJoinPoint point) throws Throwable {
    
    

            // 1 获取当前方式上是否有 mylog这个注解
            MethodSignature signature = (MethodSignature) point.getSignature();
            Method method = signature.getMethod();

            Result result = (Result) point.proceed(point.getArgs());

            // 判断当前函数是否有  mylog这个注解
            MyLog annotation = method.getAnnotation(MyLog.class);

            if(annotation != null){
    
    

                System.out.println("小伙伴们真帅");



            }

            return result;

    }

}    

猜你喜欢

转载自blog.csdn.net/fengzi_big/article/details/120979984