Spring-aop特点,专业术语及案例演示2

简介: Spring-aop特点,专业术语及案例演示2

三.案例演示

1.前置通知

1.1 先准备接口

package com.YU.aop.biz;
public interface IBookBiz {
  // 购书
  public boolean buy(String userName, String bookName, Double price);
  // 发表书评
  public void comment(String userName, String comments);
}

1.2然后再准备好实现类

package com.YU.aop.biz.impl;
import com.YU.aop.biz.IBookBiz;
import com.YU.aop.exception.PriceException;
public class BookBizImpl implements IBookBiz {
  public BookBizImpl() {
    super();
  }
  public boolean buy(String userName, String bookName, Double price) {
    // 通过控制台的输出方式模拟购书
    if (null == price || price <= 0) {
      throw new PriceException("book price exception");
    }
    System.out.println(userName + " buy " + bookName + ", spend " + price);
    return true;
  }
  public void comment(String userName, String comments) {
    // 通过控制台的输出方式模拟发表书评
    System.out.println(userName + " say:" + comments);
  }
}

1.3对我们的目标对象进行JavaBean配置

<!--目标对象-->
    <bean class="com.YU.aop.biz.impl.BookBizImpl" id="bookBiz"></bean>

1.4 编写前置系统日志通知

package com.YU.aop.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.aop.MethodBeforeAdvice;
/**
 * 买书、评论前加系统日志
 * @author YU
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
  @Override
  public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
//    在这里,可以获取到目标类的全路径及方法及方法参数,然后就可以将他们写到日志表里去
    String target = arg2.getClass().getName();
    String methodName = arg0.getName();
    String args = Arrays.toString(arg1);
    System.out.println("【前置通知:系统日志】:"+target+"."+methodName+"("+args+")被调用了");
  }
}

1.5配置系统通知XML中的JavaBean

<!--通知-->
    <bean class="com.YU.aop.advice.MyMethodBeforeAdvice" id="myMethodBeforeAdvice"></bean>

1.6 配置代理XML中的JavaBean

<!-- 代理-->
    <bean class="org.springframework.aop.framework.ProxyFactoryBean" id="bookProxy">
        <!-- 配置目标对象 -->
        <property name="target" ref="bookBiz"></property>
        <!-- 配置代理接口,目标对象的接口 -->
        <property name="proxyInterfaces">
            <value>com.YU.aop.biz.IBookBiz</value>
        </property>
        <property name="interceptorNames">
            <list>
                <value>myMethodBeforeAdvice</value>
            </list>
        </property>
    </bean>

1.7 测试代码开始测试

package com.YU.aop.test;
import com.YU.aop.biz.IBookBiz;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
 * @author YU
 * @create 2023-08-17 15:14
 */
public class Test1 {
    public static void main(String[] args) {
        //建模
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
//        IBookBiz bookBiz = (IBookBiz) context.getBean("bookBiz");
        IBookBiz bookBiz = (IBookBiz) context.getBean("bookProxy");
        bookBiz.buy("死仔","我的26岁女房客",18.8d);
        bookBiz.comment("死仔","真好看");
    }
}

测试结果:

由测试结果可得知,不仅获取到了我们的参数,同时根据方法获取到了我们的系统日志,也就是前置通知

2. 后置通知

2.1 先准备好后置通知的系统日志

package com.zking.aop.advice;
import java.lang.reflect.Method;
import java.util.Arrays;
import org.springframework.aop.AfterReturningAdvice;
/**
 * 买书返利
 * @author Administrator
 *
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {
  @Override
  public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
    String target = arg3.getClass().getName();
    String methodName = arg1.getName();
    String args = Arrays.toString(arg2);
    System.out.println("【后置通知:买书返利】:"+target+"."+methodName+"("+args+")被调用了,"+"该方法被调用后的返回值为:"+arg0);
  }
}

2.2 配置后置系统通知的XML的JavaBean

<!--后置通知-->
    <bean class="com.YU.aop.advice.MyAfterReturningAdvice" id="myAfterReturningAdvice"></bean>

并在前面已经配置好的代理接口中添加一个value值

2.3 测试结果

由测试结果我们可以得知,后置通知永远都在方法执行后才会显示通知,与前置通知不同的是每次前面的方法调用后都会返回一个参数

3.环绕通知

3.1 环绕通知就是前置通知和后置通知的结合,在实际应用开发中,我们一般不会单独编写前置通知和后置通知,单独使用前置通知或者后置通知时,我们会使用环绕通知,将里面前置(后置)通知的功能注释,以达到单独使用的目的

3.2 环绕通知的系统日志

package com.YU.aop.advice;
import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 * 环绕通知
 *  包含了前置和后置通知
 * 
 * @author Administrator
 *
 */
public class MyMethodInterceptor implements MethodInterceptor {
  @Override
  public Object invoke(MethodInvocation arg0) throws Throwable {
    String target = arg0.getThis().getClass().getName();
    String methodName = arg0.getMethod().getName();
    String args = Arrays.toString(arg0.getArguments());
    System.out.println("【环绕通知调用前:】:"+target+"."+methodName+"("+args+")被调用了");
//    arg0.proceed()就是目标对象的方法
    Object proceed = arg0.proceed();
    System.out.println("【环绕通知调用后:】:该方法被调用后的返回值为:"+proceed);
    return proceed;
  }
}

3.3 配置环绕通知的XML的JavaBean与前置通知和后置通知一致

3.4 测试结果

由测试结果得知,环绕通知就是前置通知和后置通知的结合,优点就是不需要再多次去进行配置及编码,所以就像我们前面所说在实际开发应用中我们一般都会选择使用环绕通知

4.异常通知

4.1 异常通知的系统日志和其他系统日志不同的是,方法名为固定的afterThrowing,不能修改

package com.YU.aop.advice;
import org.springframework.aop.ThrowsAdvice;
import com.YU.aop.exception.PriceException;
/**
 * 出现异常执行系统提示,然后进行处理。价格异常为例
 * @author Administrator
 *
 */
public class MyThrowsAdvice implements ThrowsAdvice {
  public void afterThrowing(PriceException ex) {
    System.out.println("【异常通知】:当价格发生异常,那么执行此处代码块!!!");
  }
}

4.2 在我们正常程序出问题没有去配置异常通知时会出现报错,并且不会执行后面的后置通知,如以下情况

4.3 异常处理配置和前面的配置相同

4.4 当我们配置好异常通知模块时,程序出现异常时会上报日志进行提示

5.过滤通知

5.1 直接在XML中配置JavaBean

<!--过滤通知-->
    <bean class="org.springframework.aop.support.RegexpMethodPointcutAdvisor" id="regexpMethodPointcutAdvisor">
        <property name="advice" ref="myAfterReturningAdvice"></property>
        <property name="pattern" value=".*buy"></property>
    </bean>

将图中指出部分替换成过滤通知

测试结果:

对比框中内容,在调用过buy方法后进行过滤,第二次调用时不再buy方法而是comment方法

四.总结

aop是面向切面编程,普通程序由上而下正常执行,aop的程序执行是先执行到目标对象的目标方法中,如果连接点上由前置通知,则先执行前置通知再执行目标方法,最后如果目标方法有后置通知则最后执行后置通知代码,不管是前置通知,后置通知,环绕通知,异常通知,过滤通知,代码都是非业务核心代码,如日志、事务的管理(开启、提交、回滚)        

目录
相关文章
|
27天前
|
Java Maven Spring
Spring 小案例体验创建对象的快感
本文介绍了如何在IDEA中创建一个Spring项目,包括项目创建、配置pom.xml文件以引入必要的依赖、编写实体类HelloSpring及其配置文件applicationContext.xml,最后通过测试类TestHelloSpring展示如何使用Spring的bean创建对象并调用方法。
29 0
|
4月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
4月前
|
XML Java 数据库
Spring5入门到实战------10、操作术语解释--Aspectj注解开发实例。AOP切面编程的实际应用
这篇文章是Spring5框架的实战教程,详细解释了AOP的关键术语,包括连接点、切入点、通知、切面,并展示了如何使用AspectJ注解来开发AOP实例,包括切入点表达式的编写、增强方法的配置、代理对象的创建和优先级设置,以及如何通过注解方式实现完全的AOP配置。
|
4月前
|
Java API Spring
Spring5入门到实战------1、Spring5框架概述、入门案例
这篇文章是Spring5框架的入门教程,概述了Spring框架的核心概念和特点,并通过一个创建普通Java类的案例,详细演示了从下载Spring核心Jar包、创建配置文件、编写测试代码到运行测试结果的完整流程,涵盖了Spring IOC容器的使用和依赖注入的基本用法。
|
5月前
|
开发框架 Java 开发者
Spring框架的最新功能与应用案例解析
Spring框架的最新功能与应用案例解析
|
5月前
|
存储 Java 数据中心
Spring Boot与微服务治理框架的集成成功案例
Spring Boot与微服务治理框架的集成成功案例
|
5月前
|
前端开发 Java 数据库连接
Spring6(一):入门案例
Spring6(一):入门案例
69 0
|
6月前
|
XML Java 数据库
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
Spring5系列学习文章分享---第五篇(事务概念+特性+案例+注解声明式事务管理+参数详解 )
32 0
|
6月前
|
XML Java 数据格式
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
Spring5系列学习文章分享---第三篇(AOP概念+原理+动态代理+术语+Aspect+操作案例(注解与配置方式))
57 0
|
6月前
|
JSON 安全 Java
Spring Boot与WebFlux的实战案例
Spring Boot与WebFlux的实战案例
下一篇
DataWorks