AOP 通知描述了抽取的共性功能,根据共性功能抽取的位置不同,最终运行代码时要将其加入到合理的位置
前置通知
@Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
    @Before("pt()")
    public void before() {
        System.out.println("before advice");
    } 

后置通知
@Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
@After("pt()")
    public void after() {
        System.out.println("after advice");
    } 

环绕通知(获取异常和返回值)
无对原始操作的调用
显然原始方法不执行了
 @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
 
@Around("pt()")
    public void around() {
        System.out.println("around before advice");
        System.out.println("around after advice");
    } 
 
加上对原始操作的调用
无返回值
 @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
 
@Around("pt()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        pjp.proceed();
        System.out.println("around after advice");
    } 
如果有返回值
@Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        Object obj=pjp.proceed();
        System.out.println("around after advice");
        return obj;
    } 
 

返回后通知(获取返回值)
成功运行后执行
  @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
@AfterReturning("pt()")
    public void afterReturning() {
        System.out.println("afterReturning advice");
    } 

和后置通知的区别
如果抛出异常,AfterReturning不运行,但After正常运行
抛出异常后通知(获取异常)
@Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
 
@AfterThrowing("pt()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice");
    } 

测试(通知类型,如果想看看效果,直接复制)
package org.example.dao.impl;
import org.example.dao.BookDao;
import org.springframework.stereotype.Repository;
@Repository
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println("book dao save");
    }
    public void update() {
        System.out.println("book dao update");
    }
    public void delete() {
        System.out.println("book dao delete");
    }
    public int select() {
        System.out.println("book dao select");
        return 100;
    }
}
 
package org.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan("org.example")
@EnableAspectJAutoProxy//有用注解开发的AOP
public class SpringConfig {
}
 
package org.example.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect//当作Aop处理
public class MyAdvice {
    @Pointcut("execution(void org.example.dao.BookDao.update())")
    private void pt() {
    }
    @Before("pt()")
    public void before() {
        System.out.println("before advice");
    }
    @After("pt()")
    public void after() {
        System.out.println("after advice");
    }
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        Object obj = pjp.proceed();
        System.out.println("around after advice");
        return obj;
    }
    @AfterReturning("pt()")
    public void afterReturning() {
        System.out.println("afterReturning advice");
    }
    @AfterThrowing("pt()")
    public void afterThrowing() {
        System.out.println("afterThrowing advice");
    }
}
 
package org.example.dao;
public interface BookDao {
    void save();
    void update();
    int select();
}
 
package org.example;
import org.example.config.SpringConfig;
import org.example.dao.BookDao;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
        ApplicationContext ctx=new AnnotationConfigApplicationContext(SpringConfig.class);
        BookDao bookDao=ctx.getBean(BookDao.class);
        bookDao.update();
    }
}
 
测试(获取参数,JoinPoint必须是第一位)
package org.example.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@Component
@Aspect//当作Aop处理
public class MyAdvice {
    @Pointcut("execution(* org.example.dao.BookDao.findName(..))")
    private void pt() {
    }
    @Before("pt()")
    public void before(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println("before advice:" + Arrays.toString(args));
    }
    @After("pt()")
    public void after(JoinPoint jp) {
        Object[] args = jp.getArgs();
        System.out.println("after advice:" + Arrays.toString(args));
    }
    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("around before advice");
        Object obj = pjp.proceed();
        Object[] args = pjp.getArgs();
        System.out.println("around after advice:" + Arrays.toString(args));
        return obj;
    }
    @AfterReturning(value = "pt()", returning = "res")
    public void afterReturning(Object res) {
        System.out.println("afterReturning advice:" + res);
    }
    @AfterThrowing(value = "pt()", throwing = "t")
    public void afterThrowing(Throwable t) {
        System.out.println("afterThrowing advice"+t);
    }
}
 
package org.example.dao;
public interface BookDao {
    String findName(int id);
}
 
                


















