简单AOP

Service类

import org.springframework.stereotype.Component;
 
// 代理目标类
@Component
public class BusinessService {
    public void executeBuss() {
        System.out.println("执行业务处理...");
    }
    public int add(int a, int b) {
    System.out.println("执行add业务处理...");
    return a+b;
    }
}


切面类

import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
 
/**
 * 切面配置
 */
@Component
@Aspect
public class AspectConfig {
 
    @Pointcut("execution(* com.daimeng.test..*(..))")
    private void pointCut() {
    }
 
    /**
     * 环绕通知
     */
    @Around("pointCut()")
    public Object testAround(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("@Around通知---->执行业务前打印日志...");
        Object obj = joinPoint.proceed();
        System.out.println("@Around通知---->执行业务后打印日志...");
        return obj;
    }
    
    @Before("pointCut()")
    public void before(JoinPoint join){
        //获取方法名
        String mathName=join.getSignature().getName();
        //获取参数列表
        List<Object> args = Arrays.asList(join.getArgs());
        
        System.out.println("@Before通知---->before 方法名是:"+mathName+"\t参数列表是:"+args);
    }
    
    @After("pointCut()")
    public void after(JoinPoint joinPoint){
        System.out.println("@After通知---->after....");
    }
    
    @AfterReturning(value = "pointCut()", returning = "result")
    public void logReturn(JoinPoint joinPoint, Object result) {
    System.out.println("@AfterReturning通知---->after...." + result);
    }
    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logException(JoinPoint joinPoint, Exception exception) {
    System.out.println("@AfterThrowing通知---->after....异常信息: "+ exception.getMessage());
    }
}


注册容器

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
 
@Configuration
@ComponentScan(basePackages = "com.aop.test")
@EnableAspectJAutoProxy
public class BeansConfig {
 
}


main方法

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class TestMain {
    public static void main(String[] args) {
    // 通过Java配置来实例化Spring容器
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeansConfig.class);
 
        // 在Spring容器中获取Bean对象
        BusinessService businessService = context.getBean(BusinessService.class);
        businessService.executeBuss();
        businessService.add(10, 20);
 
        // 销毁该容器
        context.destroy();
    }
}

结果

@Around通知---->执行业务前打印日志...
@Before通知---->before 方法名是:executeBuss参数列表是:[]
执行业务处理...
@Around通知---->执行业务后打印日志...
@After通知---->after....
@AfterReturning通知---->after....null
@Around通知---->执行业务前打印日志...
@Before通知---->before 方法名是:add参数列表是:[10, 20]
执行add业务处理...
@Around通知---->执行业务后打印日志...
@After通知---->after....
@AfterReturning通知---->after....30

由此可知各个切点的现后顺序

Around(前置) -> Before -> Around(后置) -> After -> AfterReturning


Around(前置) -> Before -> Around(后置) -> After -> AfterReturning

{context}