基于xml的AOP开发

x33g5p2x  于2022-08-17 转载在 其他  
字(5.2k)|赞(0)|评价(0)|浏览(910)

基于xml的AOP开发

XML配置AOP详解

切点表达式的写法

通知/(增强)的类型

前后置增强

环绕增强

异常抛出增强

最终增强

切点表达式的抽取

知识要点

基于xml的AOP开发

①导入AOP相关坐标

②创建目标接口和目标类(内部有切点)

③创建切面类(内部有增强方法)

④将目标类和切面类的对象创建权交给spring

⑤在applicationContext.xml中配置织入关系

⑥测试代码
1、导入坐标

  1. <dependency>
  2. <groupId>org.aspectj</groupId>
  3. <artifactId>aspectjweaver</artifactId>
  4. <version>1.8.4</version>
  5. </dependency>

spring-context本身有aop的实现,但是aspectj更好,aspectj本身就是一个小框架。

MyAspect切面类(有增强方法)

  1. package aop;
  2. public class MyAspect {
  3. public void before(){
  4. System.out.println("前置增强....");
  5. }
  6. }

applicationContext.xml下

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  6. http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
  7. ">
  8. <!-- 目标对象-->
  9. <bean id="target" class="aop.Target"></bean>
  10. <!-- 切面对象-->
  11. <bean id="myAspect" class="aop.MyAspect"></bean>
  12. <!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
  13. <aop:config>
  14. <!-- 声明切面-->
  15. <aop:aspect ref="myAspect">
  16. <!--切面:切点+通知 -->
  17. <aop:before method="before" pointcut="execution(public void aop.Target.save())"/>
  18. </aop:aspect>
  19. </aop:config>
  20. </beans>

AopTest测试类下

  1. package aop;
  2. import org.junit.Test;
  3. import org.junit.runner.RunWith;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.test.context.ContextConfiguration;
  6. import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
  7. @RunWith(SpringJUnit4ClassRunner.class)
  8. @ContextConfiguration("classpath:applicationContext.xml")
  9. public class AopTest {
  10. @Autowired
  11. private TargetInterface target;
  12. @Test
  13. public void test1(){
  14. target.save();
  15. }
  16. }

运行之后报错了

仔细一看需要Junit4.12以上的版本,改完之后,

 XML配置AOP详解

切点表达式的写法

表达式语法:

  1. execution(修饰符] 返回值类型  包名.类名.方法名(参数))
  •  访问修饰符可以省略
  • 返回值类型、包名、类名、方法名可以使用星号*代表任意
  • 包名与类名之间一个点.代表当前包下的类,两个点..表示当前包及其子包下的类
  • 参数列表可以使用两个点..表示任意个数,任意类型的参数列表

例如

通知/(增强)的类型

通知的配置语法:

  1. <aop:通知类型 method="切面类中的方法名" pointcut="切点表达式"/>

** 前后置增强**

  1. <!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
  2. <aop:config>
  3. <!-- 声明切面-->
  4. <aop:aspect ref="myAspect">
  5. <!--切面:切点+通知 -->
  6. <aop:before method="before" pointcut="execution(public void aop.Target.save())"/>
  7. <aop:after-returning method="afterReturn" pointcut="execution(public void aop.Target.save())"/>
  8. </aop:aspect>
  9. </aop:config>

写下前后置增强

  1. public class MyAspect {
  2. public void before(){
  3. System.out.println("前置增强....");
  4. }
  5. public void afterReturn(){
  6. System.out.println("后置增强....");
  7. }
  8. }

运行之后

 环绕增强

切面类中的方法 

  1. import org.aspectj.lang.ProceedingJoinPoint;
  2. public class MyAspect
  3. //ProceedingJoinPoint:正在执行的连接点===切点
  4. public Object around(ProceedingJoinPoint point) throws Throwable {
  5. System.out.println("环绕前增强...");
  6. Object proceed=point.proceed();//切点方法
  7. System.out.println("环绕后增强...");
  8. return proceed;
  9. }
  10. }

applicationContext.xml下

  1. <aop:config>
  2. <!-- 声明切面-->
  3. <aop:aspect ref="myAspect">
  4. <!--切面:切点+通知 -->
  5. <aop:around method="around" pointcut="execution(public void aop.Target.save())"/>
  6. </aop:aspect>
  7. </aop:config>
  8. </beans>

运行结果

  异常抛出增强

切面类下

  1. public void afterThrows(){
  2. System.out.println("异常抛出增强");
  3. }

目标类中需要手动加一个异常

  1. public class Target implements TargetInterface {
  2. @Override
  3. public void save() {
  4. System.out.println("save running。。。");
  5. int i=1/0;
  6. }
  7. }

applicationContext.xml中

  1. <!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
  2. <aop:config>
  3. <!-- 声明切面-->
  4. <aop:aspect ref="myAspect">
  5. <!--切面:切点+通知 -->
  6. <aop:after-throwing method="afterThrows" pointcut="execution(public void aop.Target.save())"/>
  7. </aop:aspect>
  8. </aop:config>

 最终增强

最终增强即为无论抛不抛出异常,这个方法都会被执行 

  1. public void after(){
  2. System.out.println("最终增强...");
  3. }
  1. <aop:config>
  2. <!-- 声明切面-->
  3. <aop:aspect ref="myAspect">
  4. <!--切面:切点+通知 -->
  5. <aop:after-throwing method="afterThrows" pointcut="execution(public void aop.Target.save())"/>
  6. <aop:after method="after" pointcut="execution(public void aop.Target.save())"/>
  7. </aop:aspect>
  8. </aop:config>

运行结果

 切点表达式的抽取

当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式。

  1. <aop:pointcut id="myPointcut" expression="execution(public void aop.Target.save())"/>

applicationContext.xml中

  1. <!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
  2. <aop:config>
  3. <!-- 抽取切点表达式 -->
  4. <aop:pointcut id="myPointcut" expression="execution(public void aop.Target.save())"/>
  5. <!-- 声明切面-->
  6. <aop:aspect ref="myAspect">
  7. <!--切面:切点+通知 -->
  8. <aop:around method="around" pointcut-ref="myPointcut"/>
  9. <aop:after-returning method="after" pointcut-ref="myPointcut"/>
  10. </aop:aspect>
  11. </aop:config>

运行结果

 知识要点

aop织入

通知的类型:前置通知、后置通知、环绕通知、异常抛出通知、最终通知

点表达式的写法

相关文章