基于xml的AOP开发

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

基于xml的AOP开发

XML配置AOP详解

切点表达式的写法

通知/(增强)的类型

前后置增强

环绕增强

异常抛出增强

最终增强

切点表达式的抽取

知识要点

基于xml的AOP开发

①导入AOP相关坐标

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

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

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

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

⑥测试代码
1、导入坐标

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

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

MyAspect切面类(有增强方法)

package aop;

public class MyAspect {
   public void before(){
       System.out.println("前置增强....");
   }
}

applicationContext.xml下

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

    <!--    目标对象-->
    <bean id="target" class="aop.Target"></bean>

    <!--    切面对象-->
    <bean id="myAspect" class="aop.MyAspect"></bean>

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

AopTest测试类下

package aop;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {

@Autowired
    private TargetInterface target;

@Test
    public void test1(){
    target.save();
}

}

运行之后报错了

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

 XML配置AOP详解

切点表达式的写法

表达式语法:

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

例如

通知/(增强)的类型

通知的配置语法:

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

** 前后置增强**

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

写下前后置增强

public class MyAspect {
   public void before(){
       System.out.println("前置增强....");
   }
   public void afterReturn(){
       System.out.println("后置增强....");
   }
}

运行之后

 环绕增强

切面类中的方法 

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspect    
//ProceedingJoinPoint:正在执行的连接点===切点
  public Object around(ProceedingJoinPoint point) throws Throwable {
      System.out.println("环绕前增强...");
      Object proceed=point.proceed();//切点方法
      System.out.println("环绕后增强...");
      return proceed;
   }
}

applicationContext.xml下

<aop:config>
<!--  声明切面-->
       <aop:aspect ref="myAspect">
           <!--切面:切点+通知   -->

      <aop:around method="around" pointcut="execution(public void aop.Target.save())"/>
       </aop:aspect>
   </aop:config>
</beans>

运行结果

  异常抛出增强

切面类下

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

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

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

applicationContext.xml中

<!--配置织入 告诉spring框架,哪些方法(切点)需要进行哪些增强(前置、后置...)引入aop命名空间-->
   <aop:config>
<!--  声明切面-->
       <aop:aspect ref="myAspect">
           <!--切面:切点+通知   -->

      <aop:after-throwing method="afterThrows" pointcut="execution(public void aop.Target.save())"/>
       </aop:aspect>
   </aop:config>

 最终增强

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

public void after(){
       System.out.println("最终增强...");
   }
<aop:config>
<!--  声明切面-->
       <aop:aspect ref="myAspect">
           <!--切面:切点+通知   -->

      <aop:after-throwing method="afterThrows" pointcut="execution(public void aop.Target.save())"/>
      <aop:after method="after" pointcut="execution(public void aop.Target.save())"/>
       </aop:aspect>
   </aop:config>

运行结果

 切点表达式的抽取

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

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

applicationContext.xml中

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

运行结果

 知识要点

aop织入

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

点表达式的写法

相关文章