创建Springboot项目,项目结构如下,直接贴上代码注释在代码里面
如果使用的是社区版本的idea,可以使用插件Spring Assistant创建项目
package com.example.demo.aop;
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 AopAnnotation {
}
package com.example.demo.aop;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
@Aspect
@Component
@Slf4j
public class AspectDemo {
/**
* 切入点
* 1.可以是注解标记的方法
* @Pointcut("@annotation(com.example.demo.aop.AopAnnotation)")
* 2.可以是某个包路径下的所有类的所有方法
* execution(* com.example.demo.service.impl..*(..))
* 说明:
* execution() 表达式的主体;
* 第一个”*“符号 表示返回值的类型任意;
* com.example.demo.service.impl 包名;
* 包名后面的”..“ 表示当前包及子包;一个.表示当前包不包含子包
* 第二个”*“ 表示类名,*即所有类;*Impl表示所有以Impl结尾的类
* .*(..) 表示任何方法名,括号表示参数,两个点表示任何参数类型;
*/
@Pointcut("execution(public * com.example.demo.service.impl..*Impl.*(..))")
// @Pointcut("@annotation(com.example.demo.aop.AopAnnotation)")
public void pointcutTarget() {
}
/**
* 前置通知,方法执行前执行
*/
@Before("pointcutTarget()")
public void beforeNotice() {
System.out.println("Before");
}
/**
* 后置通知,方法执行后执行,相当于finally,方法抛出异常也会执行
*/
@After("pointcutTarget()")
public void afterNotice() {
System.out.println("After");
}
/**
* 环绕通知,即方法执行时执行
*
* @param pjp
* @return
* @throws Throwable 异常不处理,
*/
@Around("pointcutTarget()")
public Object AroundNotice(ProceedingJoinPoint pjp) throws Throwable {
//目标方法
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
//入参
Object[] args = pjp.getArgs();
System.out.println("环绕开始...");
StopWatch watch = new StopWatch();
watch.start();
//执行目标方法
Object retValue = null;
try {
retValue = pjp.proceed();
} catch (Throwable throwable) {
throw throwable;
} finally {
watch.stop();
LogEntity build = LogEntity.builder()
.targetMethod(methodSignature.toString())
.param(args)
.result(retValue)
.time(watch.getTotalTimeMillis())
.build();
log.info(JSON.toJSONString(build));
}
System.out.println("环绕结束...");
return retValue;
}
}
package com.example.demo.aop;
import lombok.Builder;
import lombok.Data;
import lombok.ToString;
@Data
@Builder
@ToString
public class LogEntity {
private Object result;
private Object param;
private String targetMethod;
private Long time;
}
package com.example.demo.service.impl;
import com.example.demo.aop.AopAnnotation;
import com.example.demo.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
@Override
@AopAnnotation
public String getUser(String name, Integer age) {
// int i = 10/0;
return name+age;
}
}
package com.example.demo.service;
public interface UserService {
String getUser(String name, Integer age);
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
package com.example.demo;
import com.example.demo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
UserService userService;
@Test
void contextLoads() {
System.out.println(userService.getUser("张三",20));
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.75</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
运行结果
这就是一个打印日志的demo,如果完善需要排除file类型的文件打印,以及byte[]