详解Spring Aop实例之xml配置

AOP的配置方式有2种方式:xml配置和AspectJ注解方式。今天我们就来实践一下xml配置方式。

我采用的jdk代理,所以首先将接口和实现类代码附上

package com.tgb.aop;
public interface UserManager { 

  public String findUserById(int userId);
} 

package com.tgb.aop; 

public class UserManagerImpl implements UserManager { 

  public String findUserById(int userId) {
    System.out.println("---------UserManagerImpl.findUserById()--------");
    if (userId <= 0) {
      throw new IllegalArgumentException("该用户不存在!");
    }
    return "张三";
  }
}

单独写一个Advice通知类进行测试。这个通知类可以换成安全性检测、日志管理等等。

package com.tgb.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
 /**
 * Advice通知类
 * 测试after,before,around,throwing,returning Advice.
 * @author Admin
 *
 */
public class XMLAdvice { 

  /**
   * 在核心业务执行前执行,不能阻止核心业务的调用。
   * @param joinPoint
   */
  private void doBefore(JoinPoint joinPoint) {
    System.out.println("-----doBefore().invoke-----");
    System.out.println(" 此处意在执行核心业务逻辑前,做一些安全性的判断等等");
    System.out.println(" 可通过joinPoint来获取所需要的内容");
    System.out.println("-----End of doBefore()------");
  } 

  /**
   * 手动控制调用核心业务逻辑,以及调用前和调用后的处理,
   *
   * 注意:当核心业务抛异常后,立即退出,转向After Advice
   * 执行完毕After Advice,再转到Throwing Advice
   * @param pjp
   * @return
   * @throws Throwable
   */
  private Object doAround(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("-----doAround().invoke-----");
    System.out.println(" 此处可以做类似于Before Advice的事情"); 

    //调用核心逻辑
    Object retVal = pjp.proceed(); 

    System.out.println(" 此处可以做类似于After Advice的事情");
    System.out.println("-----End of doAround()------");
    return retVal;
  } 

  /**
   * 核心业务逻辑退出后(包括正常执行结束和异常退出),执行此Advice
   * @param joinPoint
   */
  private void doAfter(JoinPoint joinPoint) {
    System.out.println("-----doAfter().invoke-----");
    System.out.println(" 此处意在执行核心业务逻辑之后,做一些日志记录操作等等");
    System.out.println(" 可通过joinPoint来获取所需要的内容");
    System.out.println("-----End of doAfter()------");
  } 

  /**
   * 核心业务逻辑调用正常退出后,不管是否有返回值,正常退出后,均执行此Advice
   * @param joinPoint
   */
  private void doReturn(JoinPoint joinPoint) {
    System.out.println("-----doReturn().invoke-----");
    System.out.println(" 此处可以对返回值做进一步处理");
    System.out.println(" 可通过joinPoint来获取所需要的内容");
    System.out.println("-----End of doReturn()------");
  } 

  /**
   * 核心业务逻辑调用异常退出后,执行此Advice,处理错误信息
   * @param joinPoint
   * @param ex
   */
  private void doThrowing(JoinPoint joinPoint,Throwable ex) {
    System.out.println("-----doThrowing().invoke-----");
    System.out.println(" 错误信息:"+ex.getMessage());
    System.out.println(" 此处意在执行核心业务逻辑出错时,捕获异常,并可做一些日志记录操作等等");
    System.out.println(" 可通过joinPoint来获取所需要的内容");
    System.out.println("-----End of doThrowing()------");
  }
}

只有Advice还不行,还需要在application-config.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"
     xmlns:tx="http://www.springframework.org/schema/tx"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> 

  <bean id="userManager" class="com.tgb.aop.UserManagerImpl"/> 

  <!--<bean id="aspcejHandler" class="com.tgb.aop.AspceJAdvice"/>-->
  <bean id="xmlHandler" class="com.tgb.aop.XMLAdvice" />
  <aop:config>
    <aop:aspect id="aspect" ref="xmlHandler">
      <aop:pointcut id="pointUserMgr" expression="execution(* com.tgb.aop.*.find*(..))"/>
      <aop:before method="doBefore" pointcut-ref="pointUserMgr"/>
      <aop:after method="doAfter" pointcut-ref="pointUserMgr"/>
      <aop:around method="doAround" pointcut-ref="pointUserMgr"/>
      <aop:after-returning method="doReturn" pointcut-ref="pointUserMgr"/>
      <aop:after-throwing method="doThrowing" throwing="ex" pointcut-ref="pointUserMgr"/>
    </aop:aspect>
  </aop:config>
</beans> 

编一个客户端类进行测试一下:

package com.tgb.aop;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext; 

public class Client { 

  public static void main(String[] args) {
    BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserManager userManager = (UserManager)factory.getBean("userManager"); 

    //可以查找张三
    userManager.findUserById(1); 

    System.out.println("=====我==是==分==割==线====="); 

    try {
      // 查不到数据,会抛异常,异常会被AfterThrowingAdvice捕获
      userManager.findUserById(0);
    } catch (IllegalArgumentException e) {
    }
  }
} 

结果如图:

值得注意的是Around与Before和After的执行顺序。3者的执行顺序取决于在xml中的配置顺序。图中标记了3块,分别对应Before,Around,After。其中②中包含有③。这是因为aop:after配置到了aop:around的前面,如果2者调换一下位置,这三块就会分开独立显示。如果配置顺序是aop:after  -> aop:around ->aop:before,那么①和③都会包含在②中。这种情况的产生是由于Around的特殊性,它可以做类似于Before和After的操作。当安全性的判断不通过时,可以阻止核心业务逻辑的调用,这是Before做不到的。

使用xml可以对aop进行集中配置。很方便而简单。可以对所有的aop进行配置,当然也可以分开到单独的xml中进行配置。当需求变动时,不用修改代码,只要重新配置aop,就可以完成修改操作。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • spring中aop的xml配置方法实例详解

    前言 AOP:即面向切面编程,是一种编程思想,OOP的延续.在程序开发中主要用来解决一些系统层面上的问题,比如日志,事务,权限等等. aop,面向切面编程的目标就是分离关注点,比如:一个骑士只需要关注守护安全,或者远征,而骑士辉煌一生的事迹由谁来记录和歌颂呢,当然不会是自己了,这个完全可以由诗人去歌颂,比如当骑士出征的时候诗人可以去欢送,当骑士英勇牺牲的时候,诗人可以写诗歌颂骑士的一生.那么骑士只需要关注怎么打仗就好了.而诗人也只需要关注写诗歌颂和欢送就好了,那么这样就把功能分离了.所以可以把诗

  • Spring使用AspectJ注解和XML配置实现AOP

    本文演示的是Spring中使用AspectJ注解和XML配置两种方式实现AOP 下面是使用AspectJ注解实现AOP的Java Project 首先是位于classpath下的applicationContext.xml文件 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmln

  • 详解Spring Aop实例之xml配置

    AOP的配置方式有2种方式:xml配置和AspectJ注解方式.今天我们就来实践一下xml配置方式. 我采用的jdk代理,所以首先将接口和实现类代码附上 package com.tgb.aop; public interface UserManager { public String findUserById(int userId); } package com.tgb.aop; public class UserManagerImpl implements UserManager { publ

  • 详解Spring Aop实例之AspectJ注解配置

    上篇<Spring Aop实例之xml配置>中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop. 依旧采用的jdk代理,接口和实现类代码请参考上篇博文.主要是将Aspect类分享一下: package com.tgb.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Aft

  • 详解Spring AOP自定义可重复注解没有生效问题

    目录 1. 问题背景 2. 不啰嗦,上代码 3. 问题排查 3.1 是不是切点写得有问题,于是换成如下形式: 3.2 是不是使用的地方不是代理对象 4. 问题原因 1. 问题背景 工作中遇到这样的场景:某个方法需要在不同的业务场景下执行特定的逻辑,该方法已经上生产,不想改变原来的代码,因此决定用AOP做个切面执行逻辑. 2. 不啰嗦,上代码 以下为核心代码: 定义注解: @Target({ElementType.TYPE, ElementType.METHOD}) @Retention(Rete

  • 详解Spring AOP 拦截器的基本实现

    一个程序猿在梦中解决的 Bug 没有人是不做梦的,在所有梦的排行中,白日梦最令人伤感.不知道身为程序猿的大家,有没有睡了一觉,然后在梦中把睡之前代码中怎么也搞不定的 Bug 给解决的经历?反正我是有过. 什么是 AOP ? AOP 为 Aspect Oriented Programming 的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP 是 OOP 的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生

  • 详解Spring AOP 实现“切面式”valid校验

    why: 为什么要用aop实现校验? answer: spring mvc 默认自带的校验机制 @Valid + BindingResult, 但这种默认实现都得在Controller方法的中去接收BindingResult,从而进行校验. eg: if (result.hasErrors()) { List<ObjectError> allErrors = result.getAllErrors(); List<String> errorlists = new ArrayList

  • 详解Spring mvc的web.xml配置说明

    在说明web.xml配置之前我们先来了解一下需要配置的配置项的作用. 1.监听器(listener) 事件监听,js里应用广泛,各种事件函数的实现,Android和java se也是广泛的应用,各种点击事件的监听.当触发某个事件时,会触发监听在该事件上的所有监听器.spring 的 org.springframework.web.context.ContextLoaderListener 就是实现了 ServletContextListener 接口的监听器,该监听器会在容器(tomcat,je

  • 详解Spring AOP

    目录 什么是AOP? AOP术语 通知(Advice) 连接点(Join point) 切点(Pointcut) 连接点和切点的区别 切面(Aspect) 引入(Introduction) 织入(Weaving) SpringAOP SpringAOP的特点 SpringBoot集成SpringAOP - 依赖引入 - 创建注解 - 定义切面 - 设置切点 - 业务接口编写 - 测试 通知时机 - 正常情况 - 异常情况 总结 什么是AOP? ​AOP,即我们平时经常提到的面向切面编程.首先我们

  • 详解Spring AOP 实现主从读写分离

    深刻讨论为什么要读写分离? 为了服务器承载更多的用户?提升了网站的响应速度?分摊数据库服务器的压力?就是为了双机热备又不想浪费备份服务器?上面这些回答,我认为都不是错误的,但也都不是完全正确的.「读写分离」并不是多么神奇的东西,也带不来多么大的性能提升,也许更多的作用的就是数据安全的备份吧. 从一个库到读写分离,从理论上对服务器压力来说是会带来一倍的性能提升,但你仔细思考一下,你的应用服务器真的很需要这一倍的提升么?那倒不如你去试着在服务器使用一下缓存系统,如 Memcached.Redis 这

  • 详解Spring Boot 部署与服务配置

    spring Boot 其默认是集成web容器的,启动方式由像普通Java程序一样,main函数入口启动.其内置Tomcat容器或Jetty容器,具体由配置来决定(默认Tomcat).当然你也可以将项目打包成war包,放到独立的web容器中(Tomcat.weblogic等等),当然在此之前你要对程序入口做简单调整. 项目构建我们使用Maven或Gradle,这将使项目依赖.jar包管理.以及打包部署变的非常方便. 一.内嵌 Server 配置 Spring Boot将容器内置后,它通过配置文件

  • 详解Spring Cloud Zuul中路由配置细节

    上篇文章我们介绍了API网关的基本构建方式以及请求过滤,小伙伴们对Zuul的作用应该已经有了一个基本的认识,但是对于路由的配置我们只是做了一个简单的介绍,本文我们就来看看路由配置的其他一些细节. 首先我们来回忆一下上篇文章我们配置路由规则的那两行代码: zuul.routes.api-a.path=/api-a/** zuul.routes.api-a.serviceId=feign-consumer 我们说当我的访问地址符合/api-a/**规则的时候,会被自动定位到feign-consume

随机推荐