当前位置: 代码迷 >> 综合 >> Spring4.x学习笔记 ——AOP概念及基础操作
  详细解决方案

Spring4.x学习笔记 ——AOP概念及基础操作

热度:42   发布时间:2023-12-02 07:40:55.0

一、AOP相关概念及原理

1、发展过程

假设对于一个存在的类Student,对其进行功能扩展:

  • 传统方式:直接在源码中修改;麻烦易错,不好维护
  • 纵向抽取机制扩展:如写一个扩展类,在该类中写扩展方法,让Student基础该类,调用该类的扩展方法;耦合度仍然过高,当父类改变时,仍需要调整Student中的调用形式(如方法名改变、参数改变等)
  • 横向抽取机制扩展:及面向切面的思想(AOP),采用动态代理的原理实现。
    • 情况一:Studnent实现了某个接口,创建一个与Student**同级**的实现该接口的代理对象进行扩展,及JDK动态代理
    • 情况二:Student没有实现接口,则创建Student子类的代理对象,在子类中调用super(父类)中的方法,完成加强,即cglib动态代理

2、相关概念

  • 连接点(JoinPoint):可被增强的方法
  • 切入点(PointCut):实际增强的方法
  • 通知/增强(Advice):实际增强的功能

    • 前置通知:在方法之前增强
    • 后置通知:在方法之后增强
    • 异常通知:方法出现异常后增强
    • 最终通知:在后置之后通知
    • 环绕通知:增强的方法要加(ProceedingJoinPoint pjp)形参,调用pjp.proceed();即调用带增强的方法
  • 切面:把增强应用到切入点的过程

二、Spring与Aspectj进行AOP操作(xml配置方式)

1、引入aop的jar包 aopalliance、aspectjweaver、spring-aop、spring-aspects

2、加约束

<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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
</Beans>

3、创建Student类及切入点的类StudentAdd

public class Student {public void Show() {System.out.println("原始:我是一个小学生...");}
}
public class StudentAdd {//前置增强public void ShowBefore() {System.out.println("前置:我的名字叫小明...");}//后置增强public void ShowAfter() {System.out.println("后置:我上二年级....");}//最终增强public void ShowFinal() {System.out.println("最终:我要好好学习...");}//环绕增强public void ShowAro(ProceedingJoinPoint pj) throws Throwable {System.out.println("前环绕:============");pj.proceed(); //执行方法System.out.println("后环绕:************");}
}

4、Aspectj配置AOP操作

<!-- 扫描包下的所有注解 --><context:component-scan base-package="com.aoptest"></context:component-scan><!-- 配置对象的创建 --><bean id="student" class="com.aoptest.test1.Student"></bean><bean id="add" class="com.aoptest.test1.StudentAdd"></bean><!-- aop配置 --><aop:config><!-- 配置切入点(那些方法要增强) --><aop:pointcut expression="execution(* com.aoptest.test1.Student.Show(..))" id="show"/><!-- 切面配置(将增强应用到上面的方法) --><aop:aspect ref="add"><aop:before method="ShowBefore" pointcut-ref="show"/> <!-- 前置通知 --><aop:after method="ShowFinal" pointcut-ref="show"/> <!-- 最终通知 --><aop:after-returning method="ShowAfter" pointcut-ref="show"/> <!-- 后置通知 --><aop:around method="ShowAro" pointcut-ref="show"/> <!-- 环绕通知 --></aop:aspect></aop:config>

5、附:配置中的expression属性

<aop:pointcut expression="execution(* com.aoptest.test1.Student.Show(..))" id="show"/>
  • execution(* com.aoptest.test1.Student.Show(..)) //*代表方法类型为任意(public private等),(..)代表所有参数
  • execution(* com.aoptest.test1.Student.*(..)) //Student类中的所有方法
  • execution(* .(..)) //项目的所有方法
  • execution(* get*(..)) //以get开头的方法

二、Spring与Aspectj进行AOP操作(注解方式)

1、创建对象,仍使用上面的Student和StudentAdd类

2、Spring中配置开启AOP操作

<!-- 扫描包下的所有注解 --><context:component-scan base-package="com.aoptest"></context:component-scan><!-- 配置对象的创建 --><bean id="student" class="com.aoptest.test2.Student"></bean><bean id="add" class="com.aoptest.test2.StudentAdd"></bean><!-- aop注解方式 开启aop操作 --><aop:aspectj-autoproxy></aop:aspectj-autoproxy>

3、在”增强类”上使用注解

@Aspect
public class StudentAdd {//前置增强@Before(value = "execution(* com.aoptest.test2.Student.Show(..))")public void ShowBefore() {System.out.println("前置:我的名字叫小明...");}
}
  相关解决方案