zoukankan      html  css  js  c++  java
  • 基于XML的方式实现AOP

    1、XML配置相关元素

    我们知道注解很方便,并且是很强大的东西,并且在平时的开发中基本都会使用注解开发,但基于 XML 的方式我们仍然需要了解,其实就跟注解差不多的功能,只是换了一种形式,下面先来了解一下 AOP 中可以配置的元素:

    AOP 配置元素 用途
    aop:advisor 定义 AOP 的通知其(一种很古老的方式,很少使用)
    aop:aspect 定义一个切面
    aop:before 定义前置通知
    aop:after 定义后置通知
    aop:around 定义环绕通知
    aop:after-returning 定义返回通知
    aop:after-throwing 定义异常通知
    aop:config 顶层的 AOP 配置元素。大多数的<aop:*>元素必须包含在<aop:config>中
    aop:declare-parents 给通知引入新的额外接口,增强功能
    aop:pointcut 定义切点

    2、基于XML配置AOP

    [1]、配置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: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.xsd
           http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <!-- 将被代理的目标类加入IOC容器 -->
        <bean class="com.thr.aop.target.UserServiceImpl" id="userService"/>
    
        <!-- 将切面类加入IOC容器 -->
        <bean class="com.thr.aop.aspect.LogXmlAspect" id="logXmlAspect"/>
    
        <!-- 配置AOP -->
        <aop:config>
    
            <!-- 声明切入点表达式 -->
            <aop:pointcut id="logPointCut" expression="execution(* *..*.*(..))"/>
    
            <!-- 配置切面,使用ref属性引用切面类对应的bean。如有需要可以使用order属性指定当前切面的优先级数值 -->
            <aop:aspect ref="logXmlAspect">
                <!-- 配置具体通知方法,通过pointcut-ref属性引用上面已声明的切入点表达式 -->
                <aop:before method="doBefore" pointcut-ref="logPointCut"/>
    
                <!-- 在返回通知中使用returning属性指定接收方法返回值的变量名 -->
                <aop:after-returning method="doAfterReturning" pointcut-ref="logPointCut" returning="returnValue"/>
    
                <!-- 在异常通知中使用throwing属性指定接收异常对象的变量名 -->
                <aop:after-throwing method="doAfterThrowing" pointcut-ref="logPointCut" throwing="throwable"/>
    
                <!-- 配置后置帖子 -->
                <aop:after method="doAfter" pointcut-ref="logPointCut"/>
            </aop:aspect>
    
        </aop:config>
    </beans>
    

    [2]、创建目标接口

    /**
     * 目标类接口
     */
    public interface IUserService {
    
        void addUser(String userName,Integer age);
    }
    

    [3]、创建目标接口实现类

    /**
     * 目标类,会被动态代理
     */
    @Service
    public class UserServiceImpl implements IUserService {
    
        @Override
        public void addUser(String userName, Integer age) {
            System.out.println(userName + ":" + age);
        }
    }
    

    [4]、创建切面类

    /**
     * 创建日志切面类
     */
    public class LogXmlAspect {
        
        public void doBefore(JoinPoint joinPoint) { // 在通知方法中,声明JoinPoint类型的形参,就可以在Spring调用当前方法时把这个类型的对象传入
    
            // 1.通过JoinPoint对象获取目标方法的签名
            // 所谓方法的签名就是指方法声明时指定的相关信息,包括方法名、方法所在类等等
            Signature signature = joinPoint.getSignature();
    
            // 2.通过方法签名对象可以获取方法名
            String methodName = signature.getName();
    
            // 3.通过JoinPoint对象获取目标方法被调用时传入的参数
            Object[] args = joinPoint.getArgs();
    
            // 4.为了方便展示参数数据,把参数从数组类型转换为List集合
            List<Object> argList = Arrays.asList(args);
    
            System.out.println("[前置通知]" + methodName + "方法开始执行,参数列表是:" + argList);
        }
    
        public void doAfterReturning(JoinPoint joinPoint, Object returnValue) {
            String methodName = joinPoint.getSignature().getName();
            System.out.println("[返回通知]" + methodName + "方法成功结束,返回值是:" + returnValue);
        }
        
        public void doAfterThrowing(JoinPoint joinPoint, Throwable throwable) {
            String methodName = joinPoint.getSignature().getName();
            System.out.println("[异常通知]" + methodName + "方法异常结束,异常信息是:" + throwable.getMessage());
        }
        
        public void doAfter(JoinPoint joinPoint) {
            String methodName = joinPoint.getSignature().getName();
            System.out.println("[后置通知]" + methodName + "方法最终结束");
        }
    }
    

    [5]、创建测试类

    public class XmlAOPTest {
    
        //创建ApplicationContext对象
        private ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    
        @Test
        public void testAOP(){
            // 1.从IOC容器中获取接口类型的对象
            IUserService userService = ac.getBean(IUserService.class);
    
            // 2.调用方法查看是否应用了切面中的通知
            userService.addUser("张三",20);
        }
    }
    

    [6]、运行结果

    image

    作者: 唐浩荣
    本文版权归作者和博客园共有,欢迎转载,但是转载需在博客的合适位置给出原文链接,否则保留追究法律责任的权利。
  • 相关阅读:
    Docker的安装和配置
    SpringBoot如何添加拦截器
    使用Java执行python代码并得到结果
    Redis高可用集群之水平扩展
    Redis集群演变和集群部署
    Redis核心原理
    Redis基本数据结构
    Redis安装和配置
    Typora+PicGo+Gitee笔记方案
    视频描述(Video Captioning)近年重要论文总结
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/14746349.html
Copyright © 2011-2022 走看看