zoukankan      html  css  js  c++  java
  • 基于 XML 的 AOP 配置(1)

    本文连接:https://www.cnblogs.com/qzhc/p/11969734.html

    接下来我将用一个很简单的实例

    1、 环境搭建

    1.1、 第一步:准备必要的代码

    业务层代码:

    AccountServiceImpl.java

    package com.henu.service.impl;
    
    import com.henu.service.AccountService;
    
    public class AccountServiceImpl implements AccountService {
        public void saveAccount() {
            System.out.println("执行了保存");
        }
    }

    测试类:

    AOPtest.java

    package com.henu.test;
    
    import com.henu.service.AccountService;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class AOPtest {
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
            AccountService as = (AccountService) ac.getBean("accountService");
            as.saveAccount();
        }
    }

    1.2、导入所需要的jar包

    我的demo是用maven管理的:pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.henu</groupId>
        <artifactId>day03_spring_adviceType</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-context</artifactId>
                <version>5.0.2.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjweaver</artifactId>
                <version>1.8.7</version>
            </dependency>
        </dependencies>
    
    </project>

    1.3、创建 spring 的配置文件并导入约束和配置spring的ioc

    <?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">
        <!--配置spring的Ioc,把service对象配置起来-->
    
        <bean id="accountService" class="com.henu.service.impl.AccountServiceImpl"></bean>
       

    1.4、写一个公共类作为通知

    logger.java

    package com.henu.utils;
    //记录日志
    public class Logger {
        /**
         * 前置通知
         * */
        public void befterPrintLog(){
            System.out.println("前置通知logger开始记录日志了");
        }
        /**
         * 后置通知
         * */
        public void afterReturningPrintLog(){
            System.out.println("后置通知logger开始记录日志了");
        }
        /**
         * 异常通知
         * */
        public void afterThrowingPrintLog(){
            System.out.println("异常通知logger开始记录日志了");
        }
        /**
         * 最终通知
         * */
        public void afterPrintLog(){
            System.out.println("最终通知logger开始记录日志了");
        }
    
    }

    2、aop配置步骤(先给代码,在讲)

    <?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">
        <!--配置spring的Ioc,把service对象配置起来-->
    
        <bean id="accountService" class="com.henu.service.impl.AccountServiceImpl"></bean>
        <!--配置logger类 -->
        <bean id="logger" class="com.henu.utils.Logger"></bean>
        <!--配置AOP-->
        <aop:config>
        <!--配置切面表达式 id属性用于指定表达式的唯一标示。execution属性用于指定表达式内容
            此标签写在aop:aspect标签内部只能当前切面使用
            他还可以写在aop:aspect外面,但必须至首,全局都可以使用
        -->
            <aop:pointcut id="pt1" expression="execution(* com.henu.service.impl.*.*(..))"/>
            <!--配置切面-->
            <aop:aspect id="logAdvice" ref="logger">
    
            <!--配置通知的类型,并且建立通知方法和切入点方法的关联-->
                <!--配置前置通知:在切入点方法执行之前-->
                <aop:before method="befterPrintLog" pointcut-ref="pt1"></aop:before>
                <!--配置后置通知:在切入点方法正常执行之后。它与异常只执行一个-->
                <aop:after-returning method="afterReturningPrintLog" pointcut-ref="pt1"></aop:after-returning>
                <!--配置异常通知:在切入点方法执行产生异常之后。它与后置只执行一个-->
                <aop:after-throwing method="afterThrowingPrintLog" pointcut-ref="pt1"></aop:after-throwing>
                <!--配置最终通知:无论切入点是否正常执行,它都会在其后面执行-->
                <aop:after method="afterPrintLog" pointcut-ref="pt1"></aop:after>
               
            </aop:aspect>
        </aop:config>
    
    </beans>

    2.1、把通知类用bean标签配置起来

    <!--配置logger类 -->
        <bean id="logger" class="com.henu.utils.Logger"></bean>

    2.2、使用aop:config声明aop配置

      aop:config:

       作用:用于声明开始 aop 的配置 

        <aop:config>

           <!--配置的代码都写在此处-->        

        </aop:config>

    2.3、使用 aop:aspect 配置切面

    aop:aspect:
      作用:
        用于配置切面。
      属性:
        id:给切面提供一个唯一标识。
        ref:引用配置好的通知类 bean 的 id。
    <aop:aspect id="logAdvice" ref="logger">
    <!--配置通知的类型要写在此处-->
    </aop:aspect>

    2.4、使用 aop:pointcut 配置切入点表达式

      大家看到,使用下面的方法,会使之前的代码减少很多

    aop:pointcut:
    作用:
    用于配置切入点表达式。就是指定对哪些类的哪些方法进行增强。
    属性:
    expression:用于定义切入点表达式。
    id:用于给切入点表达式提供一个唯一标识
    <aop:pointcut id="pt1" expression="execution(* com.henu.service.impl.*.*(..))" />

    2.4、使用aop:xxx配置对应的通知类型

         aop:before
            作用:
              用于配置前置通知。指定增强的方法在切入点方法之前执行
            属性:
              method:用于指定通知类中的增强方法名称
              ponitcut-ref:用于指定切入点的表达式的引用
              poinitcut:用于指定切入点表达式
            执行时间点:
              切入点方法执行之前执行
    <aop:before method="beginTransaction" pointcut-ref="pt1"/>
         
       aop:after-returning 作用:   用于配置后置通知 属性:   method:指定通知中方法的名称。   pointct:定义切入点表达式   pointcut-ref:指定切入点表达式的引用 执行时间点:   切入点方法正常执行之后。它和异常通知只能有一个执行
    <aop:after-returning method="commit" pointcut-ref="pt1"/>
       aop:after-throwing 作用:   用于配置异常通知 属性:   method:指定通知中方法的名称。   pointct:定义切入点表达式   pointcut-ref:指定切入点表达式的引用 执行时间点:   切入点方法执行产生异常后执行。它和后置通知只能执行一个
    <aop:after-throwing method="rollback" pointcut-ref="pt1"/>
       aop:after 作用:   用于配置最终通知 属性:   method:指定通知中方法的名称。   pointct:定义切入点表达式   pointcut-ref:指定切入点表达式的引用 执行时间点:   无论切入点方法执行时是否有异常,它都会在其后面执行。
    <aop:after method="release" pointcut-ref="pt1"/>

    2.5、切入点表达式说明

    execution:匹配方法的执行(常用)
            execution(表达式)
            表达式语法:execution([修饰符] 返回值类型 包名.类名.方法名(参数))
            写法说明:
            全匹配方式:
              public void com.henu.service.impl.AccountServiceImpl.saveAccount()
            访问修饰符可以省略
              void com.itheima.service.impl.AccountServiceImpl.saveAccount()
            返回值可以使用*号,表示任意返回值
              * com.henu.service.impl.AccountServiceImpl.saveAccount()
            包名可以使用*号,表示任意包,但是有几级包,需要写几个*.
              * *.*.*.*.AccountServiceImpl.saveAccount()
            使用..来表示当前包,及其子包
              * com..AccountServiceImpl.saveAccount()
            类名和方法名可以使用*号来实现通配
              * *..*.*()
            参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数
              * com..*.*(*)
            参数列表可以使用..表示有无参数均可,有参数可以是任意类型
              * com..*.*(..)
            全通配方式:
              * *..*.*(..)
        注:
            通常情况下,我们都是对业务层的方法进行增强,所以切入点表达式都是切到业务层实现类。
            execution(* com.henu.service.impl.*.*(..))   

    讲到这里基本都差不多了,少啥以后再补把。

  • 相关阅读:
    Redis的使用
    linux面试题
    数据库面试题
    Xadmin控件的实现:〇六查询视图四——list视图search功能
    Xadmin控件的实现:〇五查询视图三——list视图封装
    Xadmin控件的实现:〇四查询视图二——分页效果的实现
    Xadmin控件的实现:〇三查询视图一——基础功能
    Xadmin控件的实现:〇项目介绍
    Xadmin控件的实现:〇二增、改视图
    离线电商数仓(十七)之用户行为数据仓库(三)高可用mysql (HA mysql,ubuntu)
  • 原文地址:https://www.cnblogs.com/qzhc/p/11969734.html
Copyright © 2011-2022 走看看