Spring AOP的概念
## AOP面向切面编程
作用:AOP关注的是代码中的共性部分,将这些共性部分抽取出去,统一未回,在程序运行的过程中再通过
动态代理的方式将抽取出去的部分添加回去;
优点:
AOP只是OOP的补充,并不是替代OOP;
实现技术的方式: 都是使用的反射技术
Spring AOP的相关术语【重要】
目标类: 需要增强的类
目标对象: 有目标类创建的对象
连接点: 目标类中的所有方法
切入点: 具有共性功能的方法/需要增强的方法
连接点不一定是切入点,但是切入点一定是连接点
通知: 将共性功能的代码块抽取抽取形成的饭囊发 叫 通知
通知类: 通知所在的类 叫 通知类
描述通知和切入点之间的惯性系 叫 切面
Joinpoint 【连接点】
Pointout 【切入点】
Advice 【通知/曾倩】
Target 【目标对象】
Weaving 【织入】
Poxy 【代理】
配置文件进行配置
第一步:把通知类用 bean 标签配置起来
<bean id="txManager" class="com.itheima.utils.TransactionManager">
<property name="dbAssit" ref="dbAssit"></property>
</bean>
第二步:使用 aop:config 声明 aop 配置
aop:config:作用:用于声明开始 aop 的配置
<aop:config></aop:config>
第三步:使用 aop:aspect 配置切面
作用:用于配置切.
<aop:aspect id="txAdvice" ref="引入配置好的通知bean的id“>
</aop:aspect>
第四步:使用 aop:pointcut 配置切入点表达式
作用:用于配置切入点表达式。就是指定对哪些类的哪些方法进行增
<aop:pointcut expression="execution(
public void com.itheima.service.impl.AccountServiceImpl.transfer(java.lang.String, java.lang.String, java.lang.Float))" id="pt1"/>
第五步:使用 aop:xxx 配置对应的通知类型
aop:before 作用:用于配置前置通知。指定增强的方法在切入点方法之前
<aop:before method="beginTransaction" pointcut-ref="pt1"
aop:after-returning 作用:用于配置后置通知
<aop:after-returning method="commit" pointcut-ref="pt1"/>
aop:after-throwing作用:用于配置异常
<aop:after-throwing method="rollback" pointcut-ref="pt1"/>
aop:after 作用:用于配置最终通知
<aop:after method="release" pointcut-ref="pt1"/>
属性:
method:指定通知中方法的名称。
pointct:定义切入点表达式
pointcut-ref:指定切入点表达式的
环绕通知【通常情况下环绕通知都是独立使用的】
aop:around:作用:用于配置环绕通知
说明:它是 spring 框架为我们提供的一种可以在代码中手动控制增强代码什么时候执行的方式。
<aop:config>
<aop:pointcut expression="execution(* com.itheima.service.impl.*.*(..))"id="pt1"/>
<aop:aspect id="txAdvice" ref="txManager">
<!-- 配置环绕通知 -->
<aop:around method="transactionAround" pointcut-ref="pt1"/>
</aop:aspect>
</aop:config>
注解aop配置
第一步:在配置文件中导入 context 的名称空间
第二步:在配置文件中指定 spring 要扫描的包
<context:component-scan base-package="com.itheima"/>
第三步:把通知类也使用注解配置
@Component("txManager”)
第四步:在通知类上使用@Aspect 注解声明为切面
作用:把当前类声明为切面类。
@Component("txManager")
@Aspect //表明当前类是一个切面类
public class TransactionManager{}
第五步:在增强的方法上使用注解配置
@Before作用:把当前方法看成是前置通知。
属性:
value:用于指定切入点表达式,还可以指定切入点表达式的
## 演示
@Before("execution(* com.itheima.service.impl.*.*(..))
@AfterReturning("execution(* com.itheima.service.impl.*.*(..))
@AfterThrowing("execution(* com.itheima.service.impl.*.*(..))
@After("execution(* com.itheima.service.impl.*.*(..))")
public void release() {try {dbAssit.releaseConnection();}
catch (Exception e) {e.printStackTrace();
第六步:在 spring 配置文件中开启 spring 对注解 AOP 的支持
<!-- 开启 spring 对 AOP 注解的支持 -->
<aop:aspectj-autoproxy/>
`纯注解配置: <!-- 开启 spring 对 AOP 注解的支持 -->
@EnableAspectJAutoProxy
【在配置类进行注释,作用和aspectJ-autoproxy xml 配置效果相同】
环绕通知注解配置
@Around
作用:把当前方法看成是环绕通知。
属性:value:用于指定切入点表达式,还可以指定切入点表达式的引用。
@Around("execution(* com.itheima.service.impl.*.*(..))")
public Object transactionAround(ProceedingJoinPoint pjp)
{
//定义返回值
Object rtValue = null;
try {
//获取方法执行所需的参数
Object[] args = pjp.getArgs();
//前置通知:开启事务
beginTransaction();
//执行方法
rtValue = pjp.proceed(args);
//后置通知:提交事务
commit();
}catch(Throwable e) {
//异常通知:回滚事务
rollback();
e.printStackTrace();}finally {
//最终通知:释放资源
release();
}
切入点表达式进行注解
@pointcut
作用:指定切入点表
代码演示
·@Pointcut("execution(* com.itheima.service.impl.*.*(..))")
·private void pt1() {}
## 引用方式
@Around("pt1()")//注意:千万别忘了写括号
public Object transactionAround(ProceedingJoinPoint pjp) {
//定义返回值
Object rtValue = null;
try {
//获取方法执行所需的参数
Object[] args = pjp.getArgs();