

解析:
运用动态代理技术实现,创建了DeptServiceProxy代理对象,从而实现AOP的应用

AOP中的通知类型:

java
package com.itheima.aop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@Aspect
public class MyAspect1 {
//前置通知 - 目标方法运行之前运行
@Before("execution(* com.itheima.service.impl.*.*(..))")
public void before(){
log.info("before....");
}
//环绕通知 - 目标方法运行之前和之后运行
@Around("execution(* com.itheima.service.impl.*.*(..))")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
log.info("around ... before ....");
Object result = pjp.proceed();
log.info("around ... after ....");
return result;
}
//后置通知 - 目标方法运行之后运行,无论是否出现异常都会执行
@After("execution(* com.itheima.service.impl.*.*(..))")
public void after(){
log.info("after....");
}
//返回后通知 - 目标方法运行之后运行,如果出现异常不会运行
@AfterReturning("execution(* com.itheima.service.impl.*.*(..))")
public void afterReturning(){
log.info("afterReturning....");
}
//返回后通知 - 目标方法运行之后运行,只有出现异常才会运行
@AfterThrowing("execution(* com.itheima.service.impl.*.*(..))")
public void afterThrowing(){
log.info("afterThrowing....");
}
}
java
package com.itheima.aop;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Slf4j
@Component
@Aspect
public class MyAspect1 {
@Pointcut("execution(* com.itheima.service.impl.*.*(..))")
public void pt(){
}
//前置通知 - 目标方法运行之前运行
@Before("pt()")
public void before(){
log.info("before....");
}
//环绕通知 - 目标方法运行之前和之后运行
@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
log.info("around ... before ....");
Object result = pjp.proceed();
log.info("around ... after ....");
return result;
}
//后置通知 - 目标方法运行之后运行,无论是否出现异常都会执行
@After("pt()")
public void after(){
log.info("after....");
}
//返回后通知 - 目标方法运行之后运行,如果出现异常不会运行
@AfterReturning("pt()")
public void afterReturning(){
log.info("afterReturning....");
}
//返回后通知 - 目标方法运行之后运行,只有出现异常才会运行
@AfterThrowing("pt()")
public void afterThrowing(){
log.info("afterThrowing....");
}
}

通知的顺序:


可以通过@Order关键字来确定各个切面类前置通知或后置通知的顺序
execution切面表达式:


annotation切入点表达式(利用注解):
Service.impl中:
java
@LogOperation
@Override
public List<Dept> list() {
List<Dept> deptList = deptMapper.list();
return deptList;
}
一个LogOperation注解类:
java
package com.itheima.anno;
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 LogOperation {
}
切面类:
java
@Before("@annotation(com.itheima.anno.LogOperation)")
public void before(){
log.info("MyAspect4 -> before ...");
}
连接点:

