《Spring快速入门》读书笔记 第4章 Spring之AOP

        个人读书笔记,题外话都写在第1章https://blog.csdn.net/u013652550/article/details/119800308


        第4章介绍了AOP的主要概念,并列举了3种实现。

4.1 AOP基础

AOP的主要概念

横切关注点;切面;连接点;切入点;通知;目标对象;织入;引入。

4.2 AOP实现

1. 经典的基于代理的AOP

        编写拦截器实现以下接口。

接口方法
AfterReturningAdviceafterReturning(Object value, Method method, Object[] args, Object instance)
MethodBeforeAdvicebefore(Method method, Object[] args, Object instance)
ThrowsAdviceafterThrowing(Exception ex)
ThrowsAdviceafterThrowing(Method method, Object[] args, Object target, Exception ex)

        需引入spring-aop、spring-context。书上写的是在pom.xml中引入,实测还需要在XML配置文件中的beans内增加属性xmlns:aop,以及在对应的xsi:schemaLocation中补全。

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

        安装时,先借助Spring中的代理类将自定义拦截器注入NameMatchMethodPointcutAdvisor类的advice属性中,再将定义好的NameMatchMethodPointcutAdvisor对象注入ProxyFactoryBean中。

    <bean id="..." class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="interceptorNames">
            <list>
                <value>...</value>
            </list>
        </property>
        <property name="target" ref="..."/>
    </bean>

2. AspectJ基于XML的配置

        使用AspectJ时需要在pom.xml中引入两个依赖项,即aopalliance、aspectjweaver。

        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.11</version>
        </dependency>

        (现在一般都使用注解,后面这张表以及XML配置可以跳了)

AspectJ主要的配置元素
AOP配置元素描述
<aop:config>顶层的AOP配置元素,大多数的<aop:*>元素必须包含在<aop:config>元素内
<aop:aspect>定义切面
<aop:aspect-autoproxy>启用@AspectJ注解驱动的切面
<aop:pointcut>定义切点
<aop:advisor>定义AOP通知器
<aop:before>定义AOP前置通知
<aop:after>定义AOP后置通知(不管被通知的方法是否执行成功)
<aop:after-returning>定义成功返回后的通知
<aop:after-throwing>定义抛出异常后的通知
<aop:around>定义AOP环绕通知
<aop:declare-parents>为被通知的对象引入额外的接口,并透明地实现

示例XML配置:

    <aop:config>
        <aop:aspect id="..." ref="...">
            <aop:pointcut id="abc" expression="..."/>
            <aop:before pointcut-ref="abc" method="..."/>
            <aop:after pointcut-ref="abc" method="..."/>
            <aop:after-returning pointcut-ref="abc" method="..." returning="..."/>
            <aop:around pointcut-ref="abc" method="..."/>
            <aop:after-throwing pointcut-ref="abc" method="..." throwing="e"/>
        </aop:aspect>
    </aop:config>

这里需要掌握一下execution表达式:Spring注解配置Aop - 乐之者v - 博客园 (cnblogs.com)

execution (* cn.itcast.service.impl.UserServiceImpl.*(..)):匹配UserServiceImpl类中声明的所有方法。第一个*代表任意修饰符及任意返回值类型,第二个*代表任意方法,..匹配任意数量任意类型的参数,若目标类与该切面在同一个包中,可以省略包名。
execution public * cn.itcast.service.impl.UserServiceImpl.*(..):匹配UserServiceImpl类中的所有公有方法。
execution public double cn.itcast.service.impl.UserServiceImpl.*(..):匹配UserServiceImpl类中返回值类型为double类型的所有公有方法。
execution public double cn.itcast.service.impl.UserServiceImpl.*(double, ..):匹配UserServiceImpl类中第一个参数为double类型,后面不管有无参数的所有公有方法,并且该方法的返回值类型为double类型。
execution public double cn.itcast.service.impl.UserServiceImpl.*(double, double):匹配UserServiceImpl类中参数类型为double,double类型的,并且返回值类型也为double类型的所有公有方法。

3. AspectJ基于注解的配置

        使用@Aspect注解定义切面(放在类声明处)。以下为各注解示例用法。execution表达式内含义为省略,不可填写三点。

@Component
@Aspect
public class XXX {
    @Before("execution(...)")
    public void beforeAdvice() {...}

    @After("execution(...)")
    public void afterAdvice() {...}

    @AfterReturning(value="execution(...)", returning="result")
    public void afterReturnAdvice(String result) {...}

    @Around("execution(...)")
    public String aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {...}

    @AfterThrowing(value="execution(...)", throwing="e")
    public void throwingAdvice(JoinPoint joinPoint, Exception e) {...}
}

        需要注意:环绕通知aroundAdvice方法体内需调用proceedingJoinPoint.proceed()以继续执行被拦截的方法。

        关于异常方法中的joinPoint参数,一般调用joinPoint.getSignature()方法后进一步获取class等信息,具体可参考:JoinPoint的用法_斜阳雨陌-CSDN博客_joinpoint

        最后注意在XML配置文件中使用<aop:aspect-autoproxy>开启即可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值