Spring AOP 自定义注解实现

162 阅读1分钟

工程结构预览

自定义注解

package com.example.springaopdemo.annotation;

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CalculateExecuteTime {
    // 表示操作是那个服务哪个模块下的操作
    String module() default  "xxxx服务";

    // 操作的类型,添加,更新,删除
    String type() default "add";

    // 操作者
    String user() default "system";

    // 操作描述
    String operation() default "";

}

切面

package com.example.springaopdemo.aspect;

import com.example.springaopdemo.annotation.CalculateExecuteTime;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;

/**
 * 切面
 */
@Aspect
@Component
public class CalculateExecuteTimeAspect {
}

切点表达式和通知

package com.example.springaopdemo.aspect;

import com.example.springaopdemo.annotation.CalculateExecuteTime;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import java.util.LinkedList;
import java.util.List;

/**
 * 切面
 */
@Aspect
@Component
public class CalculateExecuteTimeAspect {

    // 切点表达式
    @Pointcut("@annotation(com.example.springaopdemo.annotation.CalculateExecuteTime)")
    public void pointcut(){

    }

    // 在连接点出要真正执行的代码
    @Around("@annotation(log)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint, CalculateExecuteTime log) throws Throwable {

        long start = System.currentTimeMillis();
        // 模拟一下保存操作记录功能
        List<String> list = new LinkedList<>();
        list.add(log.operation());
        list.add(log.module());
        list.add(log.type());
        list.add(log.user());

        list.stream().forEach(i -> {
            System.out.println("日志记录:" + i);
        });
//        Object proceed = joinPoint.proceed();

        long executionTime = System.currentTimeMillis() - start;
        System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");

        return null;
    }
}

自定义注解注入处

package com.example.springaopdemo.test;

import com.example.springaopdemo.annotation.CalculateExecuteTime;
import org.springframework.stereotype.Service;

@Service
public class TestService {

    @CalculateExecuteTime
    public void share(String url){
        try {
            Thread.sleep(3);
        }catch (Exception e){

        }
    }
}

测试调用处

package com.example.springaopdemo;

import com.example.springaopdemo.test.TestService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

@SpringBootApplication
public class SpringAopDemoApplication {

    public static void main(String[] args) {
        ApplicationContext applicationContext = SpringApplication.run(SpringAopDemoApplication.class, args);
        TestService testService = applicationContext.getBean(TestService.class);
        testService.share("www.baidu.com/u/2014828");
    }

}

运行结果如下: