需求:自定义一个注解xxx(就是下面那个PrintTime),将添加了该注解的方法利用aop进行对方法增强
整体完整代码目录结构:
添加依赖:
<dependencies>
<!-- springboot依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.16</version>
</dependency>
<!-- lombok依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.28</version>
</dependency>
<!-- test依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<version>2.7.16</version>
</dependency>
<!--aop切入点表达式依赖 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
下面是具体代码:
切面(MyAdvice类)
/**
* 通知类(切面类)
*/
@Component
@Aspect
public class MyAdvice {
/**
* 注解切入点 下面切面绑定用了@annotation(printTime) 就不需要这个方法了
* 切入点:需要经行增强的连接点(方法)
*/
@Pointcut("@annotation(com.example.config.PrintTime)")
private void pt() {
}
/**
* 环绕通知共性方法 (切面与注解绑定)
* @param pro 执行业务方法的(必须要有)
* @param printTime 自定义注解(可以获取直接里面的属性值)
* @return 业务方法执行完的返回值
* @throws Throwable
*/
@Around("@annotation(printTime)")//用了@annotation(printTime)相当于写了上面的切入点方法pt()
public Object aroundMethod2(ProceedingJoinPoint pro, PrintTime printTime) throws Throwable {
System.out.println("=======业务方法前执行方法=======" + "当前时间:" + System.currentTimeMillis());
System.out.println("注解里面属性值:" + printTime.num());
Object result = pro.proceed();// 执行被增强的方法
System.out.println("=======业务方法后执行方法=======" + "当前时间:" + System.currentTimeMillis());
return result;
}
}
自定义注解:
/**
* 自定义注解 打印当前时间
*/
@Retention(RetentionPolicy.RUNTIME)//作用在运行时
@Target(ElementType.METHOD)//作用在方法上
public @interface PrintTime {
String num() default "zhangsan";
}
接口和实现类:
/**
* StudentService接口
*/
public interface StudentService {
String save();
String update();
}
/**
* StudentService实现
*/
@Service
public class StudentServiceImpl implements StudentService {
@Override
@PrintTime(num = "lisi")//添加了注解
public String save() {
System.out.println("=====业务方法:保存学生");
return "保存学生成功";
}
@Override
public String update() {
System.out.println("=====业务方法:更新学生");
return "修改学生成功";
}
}
启动类:
@SpringBootApplication
@Slf4j
@EnableAspectJAutoProxy//开启注解开发AOP功能
public class AopDemoApplication {
public static void main(String[] args) {
SpringApplication.run(AopDemoApplication.class, args);
System.out.println("**** 项目启动成功!****");
}
}
测试:
测试保存方法(添加了自定义注解@PrintTime)
测试更新方法(没有自定义注解)