Spring-AOP

2021-09-08  本文已影响0人  Zeppelin421

AOP本质:在不改变原有业务逻辑的情况下增强横切逻辑。

AOP相关术语

Joinpoint(连接点):它指的是那些可以用于把增强代码加入到业务主线中的点。这些点指的就是方法,在方法执行的前后通过动态代理技术加入增强的代码。在Spring框架AOP思想的技术实现中,也只支持方法类型的连接点
Pointcut(切入点):它指的是那些已经把增强代码加入到业务主线进来之后的连接点
Advice(通知/增强):它指的是切面类中用于提供增强功能的方法。并且不同的方法增强的时机是不一样的。其分类有:前置通知 后置通知,异常通知 最终通知 环绕通知
Target(目标对象):它指的是代理的目标对象
Proxy(代理):它指的是一个类被AOP织入增强后,产生的代理类
Weaving(织入):它指的是把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入
Aspect(切面):它指的是增强的代码所关注的方面,把这些相关的增强代码定义到一个类中,这个类就是切面类。

Spring中AOP配置方式

xml模式

<!--
    Spring基于XML的AOP配置:
    在Spring配置文件中加入aop约束
    xmlns:aop="http://www.springframework.org/schema/aop"
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd
-->
<!-- 把通知/增强bean交给spring管理 -->
<bean id="logUtil" class="com.hooda.utils.LogUtil"/>

<!-- 开始AOP配置 -->
<aop:config>
    <!-- 配置切面 -->
    <aop:aspect id="logAdvice" ref="logUtil">
        <!-- 配置前置通知 -->
        <aop:before method="printLog" pointcut="execution(public * com.hooda.service.impl.TransferServiceImpl.updateAccountByCardNo(com.hooda.pojo.Account))"/>
    </aop:aspect>
</aop:config>

xml+注解方式

<!-- 开启spring对注解aop的支持-->
<aop:aspectj-autoproxy/>
@Component
@Aspect
public class LogUtil {
    @Pointcut("execution(* com.hooda.service.impl.*.*(..))")
    public void pointcut() {}
    @Before("pointcut()")
    public void before(JoinPoint jp) {}
    @AfterReturning(value = "pointcut()", returning = "rtValue")
    public void afterReturning(Object rtValue) {}
    @AfterThrowing(value = "pointcut()", throwing="e")
    public void afterThrowing(Throwable e) {}
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) {}
}

纯注解模式

@Configuration
@ComponentScan("com.hooda")
@EnableAspectJAutoProxy
public class SpringConfiguration {
}

切入点表达式
访问修饰符 返回值 包名.包名.类名.方法名(参数列表)
全匹配方式

public void com.hooda.service.impl.TransferServiceImpl.updateAccountByCardNo(com.hooda.pojo.Account))

访问修饰符省略

void com.hooda.service.impl.TransferServiceImpl.updateAccountByCardNo(com.hooda.pojo.Account))

返回值使用*表示任意返回值

* com.hooda.service.impl.TransferServiceImpl.updateAccountByCardNo(com.hooda.pojo.Account))

包名可以使用.表示任意包,但是有几级包,必须写几个

* ....TransferServiceImpl.updateAccountByCardNo(com.hooda.pojo.Account))

包名可以使用..表示当前包及其子包

* ..TransferServiceImpl.updateAccountByCardNo(com.hooda.pojo.Account))

类名和方法名都可以使用.表示任意类,任意方法

* ...(com.hooda.pojo.Account))

参数列表可以使用具体类型。基本类型int,应用类型必须写全限定类名java.lang.String。参数列表可以使用*表示任意参数类型,但是必须有参数;参数列表可以使用..表示有无参数均可,有参数可以是任意类型

* *..*.*(*)
* *..*.*(..)

修改代理方式

<aop:config proxy-target-class="true"/>
<aop:aspectj-autoproxy proxy-target-class="true"/>

通知/增强标签
aop:before aop:after-returning aop:after-throwing aop:after aop:around
这五类标签只能出现在aop:aspect标签的内部
method:用于指定通知的方法名称
pointcut:用于指定切入点表达式
pointcut-ref:用于指定切入点表达式的引用

上一篇 下一篇

猜你喜欢

热点阅读