Spring笔记

AOP(Aspect Oriented Programming):

        面向切面编程,一种编程范式,指导开发者如何组织程序结构

        作用:在不惊动原始设计的基础上为其进行功能增强

连接点(JoinPoint):程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等

        在SpringAOP中,理解为方法的执行

切入点(Pointcut):匹配连接点的式子

        在SpringAOP中,一个切入点可以只描述一个具体方法,也可以匹配多个方法

通知(Advice):在切入点处执行的操作,也就是共性功能

        在SpringAOP中,功能最终以方法的形式呈现

通知类:定义通知的类

切面(Aspect):描述通知与切入点的对应关系

目标对象(Target):原始功能去掉共性功能对应的类产生的对象,这种对象是无法直接完成最终工作的

代理(Proxy):目标对象无法直接完成工作,需要通过原始对象的代理对象实现

 使用方法:

        @EnableAspectJAutoProxy 用注解开发AOP

        @Aspect 标记通知类

        @Pointcut(execution()) 定义切点

        @Before(切点) 将切点和通知绑定

        ①:导入aop相关坐标

        ②:定义dao接口与实现类

public interface BookDao {
    public void save();
    public void update();
}

@Repository
public class BookDaoImpl implements BookDao {
    public void save() {
        System.out.println(System.currentTimeMillis());
        System.out.println("book dao save ...");
    }
    public void update(){
        System.out.println("book dao update ...");
    }
}

        ③:定义通知类,制作通知

public class MyAdvice {
    public void before(){
        System.out.println(System.currentTimeMillis());
    }
}

        ④:定义切入点

public class MyAdvice {
    @Pointcut("execution(void dao.BookDao.update())")
    private void pt(){}
}

        ⑤:绑定切入点与通知关系,并指定通知添加到原始连接点的具体执行位置

public class MyAdvice {
    @Pointcut("execution(void com.itheima.dao.BookDao.update())")
    private void pt(){}

    @Before("pt()")
    public void before(){
        System.out.println(System.currentTimeMillis());
    }
}

AOP工作流程:

        1.Spring容器启动

        2.读取所有切面配置中的切入点

        3.初始化bean,判定bean对应的类中的方法是否匹配到任意切入点

                匹配失败,创建对象

                匹配成功,创建原始对象(目标对象)的代理对象

        4.获取bean执行方法

        获取bean,调用方法并执行,完成操作

        获取的bean是代理对象时,根据代理对象的运行模式运行原始方法与增强的内容,完成操作

AOP切入点表达式:

        格式:动作关键字(访问修饰符  返回值  包名.类/接口名.方法名(参数)异常名)

        通配符:

                * :单个独立的任意符号,可以独立出现,也可以作为前缀或者后缀的匹配符出现

                .. :多个连续的任意符号,可以独立出现,常用于简化包名与参数的书写

                +:专用于匹配子类类型

AOP通知类型:

        @Before:通知方法在原始切入点方法前运行

        @After:通知方法在原始切入点方法后运行

        @Around:通知方法在原始切入点方法前后运行

                注意事项:

                a.环绕通知必须依赖形参ProceedingJoinPoint才能实现对原始方法的调用,进而实现原始方法调用前后同时添加通知

                b.通知中如果未使用ProceedingJoinPoint对原始方法进行调用将跳过原始方法的执行

                c.对原始方法的调用可以不接收返回值,通知方法设置成void即可,如果接收返回值,必须设定为Object类型

                d.原始方法的返回值如果是void类型,通知方法的返回值类型可以设置成void,也可以设置成Object

                e.由于无法预知原始方法运行后是否会抛出异常,因此环绕通知方法必须抛出Throwable对象

@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("around before advice ...");
    Object ret = pjp.proceed();
    System.out.println("around after advice ...");
    return ret;
}

        @AfterReturning:通知方法在原始切入点方法正常执行完毕后运行

        @AfterThrowing:通知方法在原始切入点方法运行抛出异常后执行

AOP通知获取数据:

        获取切入点方法的参数

                JoinPoint:适用于前置、后置、返回后、抛出异常后通知

@Before("pt()")
public void before(JoinPoint jp) {
    Object[] args = jp.getArgs();
    System.out.println(Arrays.toString(args));
}

                ProceedJointPoint(是JoinPoint的子类):适用于环绕通知

@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    Object[] args = pjp.getArgs();
    System.out.println(Arrays.toString(args));
    Object ret = pjp.proceed();
    return ret;
}

        获取切入点方法返回值

                返回后通知

@AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(String ret) {
    System.out.println("afterReturning advice ..."+ret);
}

                环绕通知

@Around("pt()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    Object ret = pjp.proceed();
    return ret;
}

        获取切入点方法运行异常信息(了解)

                抛出异常后通知

@AfterThrowing(value = "pt()",throwing = "t")
public void afterThrowing(Throwable t) {
    System.out.println("afterThrowing advice ..."+ t);
}

                环绕通知

@Around("pt()")
public Object around(ProceedingJoinPoint pjp)  {
    Object ret = null;
    try {
        ret = pjp.proceed();
    } catch (Throwable t) {
        t.printStackTrace();
    }
    return ret;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值