Spring 09 : AOP实例

九、Spring中的AOP

1、AOP术语

  • Advice (通知/增强): 所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。 通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
  • Joinpoint (连接点): 所谓连接点是指那些被拦截到的点。在 Spring 中,这些点指的是方法,因为 Spring 只支持方法类型的 连接点。
  • Pointcut (切入点): 所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义。
  • Introduction (引介): 引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类动态地添加一些方 法或 Field。 Target(目标对象): 代理的目标对象。
  • Weaving (织入): 是指把增强应用到目标对象来创建新的代理对象的过程。 Spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。
  • Proxy(代理): 一个类被 AOP 织入增强后,就产生一个结果代理类。 Aspec t(切面): 是切入点和通知(引介)的结合。

2 、Spring中基于 xml 的 AOP 配置步骤

  1. 把通知 Bean 也交给 Spring 来管理
  2. 使用 aop : config 标签来表明开始 AOP 的设置
  3. 使用 aop : aspect 标签配置切面
    • id 属性:是给切面提供一个唯一标识
    • ref 属性:是指定通知类 Bean 的 id
  4. 在 aop : aspect 标签的内部使用对应标签来配置通知的类型
    1. aop : before 标识前置通知
      • method 属性:用于指定类中哪个放啊是前置通知
      • pointcut 属性:用于指定切入点表达式,该切入点表达式指的是对业务层中哪些方法增强
    2. 切入点表达式的写法:
      • 关键字:execution ( 表达式 )
      • 表达式:
        • 标准写法:访问修饰符 + 返回值 + 包名.类名.方法名(参数列表)
        • 举例:public void com.greyson.service.impl.IAccountServiceImpl.saveAccount ( )
      • 全通配写法:* * ..*.*(..)
        • 访问修饰符可以省略
        • 返回值可以使用通配符,表示任意返回值
        • 包名可以使用通配符,表示任意包,但是有几级包就需要写几个 *.
        • 包名可以使用 .. 表示当前包和子包
        • 类名和方法名都可以使用 * 来实现通配
        • 参数列表:
          • 可以直接使写数据类型:
            • 基本类型直接写名称(如 int )
            • 引用类型写包名.类名的方式 (如 java.lang.String )
          • 可以使用通配符表四任意类型,但是必须有参数
          • 可以使用 .. 表示有无参数即可,有参数可以是任意类型
      • 实际开发中切入点表达式的通常写法:
        • 切到业务层类实现下的所有方法:* com.greyson.service.impl.*.*(..)
      • 配置切入点表达式(aop : pointcut):
        • id属性用于指定表达式的唯一标识,expression属性用于指定表达式内容
        • 此标签写在 aop : aspect 标签内部只能当前切面使用,在其外部则所有切面可用
    3. Spring常用通知类型
      • 前置通知(aop : before):在切入点方法执行之前执行
      • 后置通知(aop : after-returning):在切入点方法正常执行之后执行,它和异常通知永远只能执行一个
      • 异常通知(aop : after-throwing):在切入点方法执行产生异常之后执行,它和后置通知永远只能执行一个
      • 最终通知(aop : after):无论切入点方法是否正常执行它都会在其后面执行
    4. 环绕通知

3、实例

  1. 引入 Maven 工程

    • Pom.xml



      4.0.0

      com.greyson
      day03_SpringAOP
      1.0-SNAPSHOT
      jar


      webapp


      org.apache.maven.plugins
      maven-compiler-plugin
      3.6.0

      1.8
      1.8





      org.springframework
      spring-context
      5.0.7.RELEASE



      org.aspectj
      aspectjweaver
      1.9.1

  2. 编写业务代码

    • IAccountService

      /**
      * 账户的业务层接口
      /
      public interface IAccountService {
      /
      *
      * 模拟保存账户
      *
      */
      void saveAccount();

      /**
      * 模拟更新账户
      * @param i
      */
      void updateAccount(int i);

      /**
      * 删除账户
      * @return
      */
      int deleteAccount();
      }

    • AccountServiceImpl

      /**
      * 账户的业务层实现类
      */
      public class AccountServiceImpl implements IAccountService {

      @Override
      public void saveAccount() {
      System.out.println("执行了保存");
      }

      @Override
      public void updateAccount(int i) {
      System.out.println("执行了更新" + i);
      }

      @Override
      public int deleteAccount() {
      System.out.println("执行了删除");
      return 0;
      }
      }

    • Logger

      /**
      * 用于记录日志的工具类,它里面提供了公共的代码
      */
      public class Logger {
      public void printLog() {
      System.out.println("lOGGER类中的printLog开始记录日志了。。。");
      }
      }

  3. 配置Spring

    • bean.xml





      aop:config

      <aop:aspect id="logAdvice" ref="logger">

      <aop:before method="printLog" pointcut="execution(* com.greyson.service.impl..(..))"></aop:before>
      </aop:aspect>
      </aop:config>

  4. 编写测试类

    • TestAOP

      /**
      * 测试AOP的配置
      */
      public class TestAOP {
      public static void main(String[] args) {
      // 1. 获取容器
      ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean.xml");
      // 2. 获取对象
      IAccountService accountService = (IAccountService)applicationContext.getBean("accountService");
      // 3. 执行方法
      accountService.saveAccount();
      accountService.updateAccount(1);
      accountService.deleteAccount();
      }
      }

posted @ 2020-06-23 13:27  Plorde  阅读(289)  评论(0)    收藏  举报