使用的编辑器:idea
一、新建springboot2项目
(1)通过spring initializr新建项目
(2)在pom.xml里加入aop的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二、新建一个测试类,并在main方法里执行他。
(1)新建测试类
import org.springframework.stereotype.Component;
@Component // 这个注解用来生成这个类的实例到spring容器
public class 被spring管理的类 {
// 构造函数
public 被spring管理的类(){
System.out.println("测试类被加载");
}
public void 普通函数1(String str){
System.out.println("普通函数1输出:"+str);
}
@自定义切面类.需要前置处理操作 // 这个是自定义注解,第三步建的。也可以先注释掉。
public void 普通函数2(String str){
System.out.println("普通函数2输出:"+str);
}
}
(2)在主函数里执行
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
// 被spring管理的类 test1 = new 被spring管理的类(); // 直接new的类不行,要从spring那里拿
被spring管理的类 test1 = context.getBean(被spring管理的类.class);
System.out.println();
test1.普通函数1("hello world");
System.out.println();
test1.普通函数2("这是一行字符串");
}
}
三、加入Aop
(1)新建aop用到的切面类
aop就像拦截器,切面类就是拦截器类,用来包含一些拦截前和拦截后执行的方法。这里的@Before指的是拦截前,也有@After拦截后等等。
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Order(900) // 这个注解用来指定多个aop方法间的执行顺序,数字越小优先级越高
@Aspect // 这个注解用来确定这个类为切面类
@Component // 这个注解用来生成这个类的实例到spring容器
public class 自定义切面类 {
public 自定义切面类(){
System.out.println("自定义aop类被加载");
}
@Order(500) // 写在方法上没有用
@Before("execution(public * com.example.demo.*.*(..))")
public void 自定义方法名(JoinPoint joinPoint)
{
System.out.println("通过表达式捕获");
}
@Order(700)
@Before("@annotation(这里要用注解的变量名_不能直接写注解名)")
// 虽然方法中我没有用到参数里的 “需要前置处理操作” ,但是必须写在参数里,因为上面的注解用到了
public void 方法名没什么要求(JoinPoint joinPoint,需要前置处理操作 这里要用注解的变量名_不能直接写注解名)
{
System.out.println("通过注解捕获");
// joinPoint.getArgs() 可以获取被捕获方法的输入参数
前置处理操作(joinPoint.getArgs()[0].toString());
}
// @Retention用来指定注解的生命周期,用在aop上,固定要 RetentionPolicy.RUNTIME
@Retention(RetentionPolicy.RUNTIME)
public @interface 需要前置处理操作 {
}
public void 前置处理操作(String str){
System.out.println(" -- 这里是前置处理操作");
System.out.println(" -- 获得参数:"+str);
}
}
@Before()里面的值,用来指定要捕获哪些东西。execution使用表达式来匹配,@annotation使用注解来匹配。
(2)现在执行主函数就可以看到效果了
这里我加入了另一个切面类,来测试@Order注解的效果
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Order(100) // 这个注解用来指定多个aop方法间的执行顺序,数字越小优先级越高
@Aspect // 这个注解用来确定这个类为aop类
@Component // 这个注解用来生成这个类的实例到spring容器
public class 自定义切面类2 {
public 自定义切面类2(){
System.out.println("自定义aop类2被加载");
}
@Order(9000) // 写在方法上没有用
@Before("execution(public * com.example.demo.*.*(..))")
public void 自定义方法名2(JoinPoint joinPoint)
{
System.out.println("通过表达式捕获2");
}
}
完整代码: