Spring 面向切面编程(AOP)


Spring 系列教程



面向切面编程(Aspect Oriented Programming/AOP)是Spring框架核心技术之一。

面向切面编程的主要作用是,在不修改源代码的情况下,可以给目标类打补丁,让其执行补丁中的代码。

例如,用户类中有个登录方法,现在需要加用户登录日志。使用AOP就不需要修改用户登录方法,只需把日志代码注入到用户登录方法前后,让其执行。日志代码就是“切面”,插入代码的地方(用户类的登录方法)就是“连接点”。

面向切面编程概念

先介绍一些AOP的概念

  • 切面(Aspect) - 一些横跨多个类的公共模块,如日志、安全、事务等。简单地说,日志模块就是一个切面。
  • 连接点(Joint Point) - 目标类中插入代码的地方。连接点可以是方法、异常、字段,连接点处的切面代码会在方法执行、异常抛出、字段修改时触发执行。
  • 建议(Advice) - 在连接点插入的实际代码(即切面的方法),有5种不同类型(后面介绍)。
  • 切点(Pointcut) - 定义了连接点的条件,一般通过正则表达式。例如,可以定义所有以loadUser开头的方法作为连接点,插入日志代码。

建议类型

  • before - 在方法之前运行建议(插入的代码)
  • after - 不管方法是否成功执行,在方法之后运行插入建议(插入的代码)
  • after-returning - 当方法执行成功,在方法之后运行建议(插入的代码)
  • after-throwing - 仅在方法抛出异常后运行建议(插入的代码)
  • around - 在方法被调用之前和之后运行建议(插入的代码)

实现

与Bean配置一样,切面也需要配置,然后由Spring容器加载。切面配置可以使用XML,或者使用“AspectJ”语法,“AspectJ”语法使用Java代码实现切面配置。

为更深理解AOP,下面实现一个日志切面的例子,例子使用XML配置。

User类

一个简单的用户类,是日志切面插入的目标类。用户类实现了几个不同的方法,这些方法会作为连接点。

User.java

public class User {
  private Integer id;
  private String name;

  public void setId(Integer id) {
    this.id = id;
  }

  public Integer getId() {
    System.out.println("Id: " + id);
    return id;
  }

  public void setName(String name) {
    this.name = name;
  }

  public String getName() {
    System.out.println("Name: " + name );
    return name;
  }

  public void printThrowException(){
    System.out.println("Exception raised");
    throw new IllegalArgumentException();
  }
}

切面 - Logging

日志切面类,定义了要插入目标类执行的方法。

Logging.java

public class Logging {
  public void beforeAdvice(){
    System.out.println("Before Advice");
  }

  public void afterAdvice(){
    System.out.println("After Advice");
  }

  public void afterReturningAdvice(Object retVal){
    System.out.println("After Advice Executed Successfully ... Returning: " + retVal.toString() );
  }

  public void AfterThrowingAdvice(IllegalArgumentException ex){
    System.out.println("There has been an exception when executing the advice: " + ex.toString());
  }
}

retVal是目标类连接点(方法)返回的值。例如,如果连接点是User类的getName()方法,该方法返回用户名称,那么retVal将被赋值用户名称。

配置

本例使用XML配置切面。

首先定义切面类的Bean,然后切面定义中引用该Bean。

切面定义中,会指明切点、插入的代码(建议),以及插入的代码怎么执行(建议类型)。

下面的示例定义了一个名为UserAllMethod的切点,使用expression="execution(* User.*(..))"匹配User类中的所有方法作为连接点。

如果想指定特定方法作为连接点,可使用execution(* User.getName(..))

示例:beans.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-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

  <aop:config>
    <!-- Aspect -->
    <aop:aspect id="loggingAspect" ref="logging">

      <!-- Pointcut -->
      <aop:pointcut id="UserAllMethods" expression="execution(* User.*(..))"/>

      <!-- Advice(s) -->
      <aop:before pointcut-ref="UserAllMethods" method="beforeAdvice"/>
      <aop:after  pointcut-ref="UserAllMethods" method="afterAdvice"/>
      <aop:after-returning pointcut-ref="UserAllMethods" returning="retVal" method="afterReturningAdvice"/>
      <aop:after-throwing  pointcut-ref="UserAllMethods" throwing="ex" method="AfterThrowingAdvice"/>
    </aop:aspect>
  </aop:config>

  <!-- The user bean -->
  <bean id="user" class="User">
      <property name="name" value="隔壁老王" />
      <property name="id" value="99"/>
  </bean>

  <!-- logging 切面定义 -->
  <bean id="logging" class="Logging"/>
</beans>

确保已经添加了依赖的JAR包,我们使用Maven,pom.xml中添加依赖:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>${springframework.version}</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjweaver</artifactId>
  <version>1.8.10</version>
</dependency>

测试切面

在main类中调用用户类的方法,查看切面是否被执行:

Test.java

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
  public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

    User user = (User) context.getBean("user");
    user.getName();
    user.printThrowException();
  }
}

原文地址:https://www.cnblogs.com/jinbuqi/p/10987723.html

时间: 2024-08-08 11:18:41

Spring 面向切面编程(AOP)的相关文章

Spring面向切面编程(AOP)

1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即实例化:spring加载完成,立即创建对象) scope:属性 singleton:默认值为单例,默认也是立即加载,在加载完成spring容器的时候,bean对象已经创建完成 prototype:多例的,默认懒加载,spring容器加载完成的时候,不会创建bean的对象,只有从容器获得bean对象的

Spring面向切面编程(AOP,Aspect&#160;Oriented&#160;Programming)

AOP为Aspect Oriented Programming的缩写,意为:面向切面编程(也叫面向方面),可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术.主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等.使用JDK的动态代理可以实现AOP. AOP通过代理的方式都程序动态统一添加功能 现在要给功能4增加一些额外的行为,如处理日志,处理权限等,可以使用代理实现.我们在功能4外面包装一个对象,假设叫A, model原来是直接调用功能4,

Spring面向切面编程AOP(around)实战

spring aop的环绕通知around功能强大,我们这里就不细说,直接上代码,看着注释就能明白 需要的可以点击下载源码 1.如果使用注解的方式则需要先创建个注解类 package com.mb.aop; import java.lang.annotation.*; /** * 常用注解说明: * 1. RetentionPolicy(保留策略)是一个enum类型,有三个值 * SOURCE -- 这个Annotation类型的信息只会保留在程序源码里,源码如果经过了编译后,Annotatio

Spring之面向切面编程AOP(二)

简介 当积累的知识点到一定量的时候,学新知识就变得容易多了.希望再接下来的学习顺利进行下去.今天知识也是挺简单的,主要就是AOP面向切面编程.其中牵涉到了JDKProxy和CGLIB两个代理类,如何使用好,加以深刻理解.学起Spring切面编程也就简单多了 代理模式 1. 代理模式介绍 代理模式的英文叫做Proxy或Surrogate,中文都可译为"代理",所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对

Spring(四):面向切面编程AOP

横切关注点:分布于应用中多处的功能 面向切面编程AOP:将横切关注点与业务逻辑相分离 在使用面向切面编程时,仍在一个地方定义通用功能,但是可以通过声明的方式定义这个功能以何种方式在何处应用,而无需修改受影响的类. 横切关注点可以被模块化为特殊的类,这些类被称为切面. 好处: 每个关注点集中于一处,而不是分散到多处代码中 服务模块更加简洁,因为它们只包含主要关注点的代码,次要关注点被转移到切面中了 1.定义AOP术语 1.1.通知(Advice) 切面的工作被称为通知. 通知定义了切面是什么以及何

Spring面向切面编程(二)简单AOP实例

简单实现一个用户登陆的功能,在用户登陆之前进行日志打印,用户登陆之后进行登陆成功日志打印. Maven添加Spring jar spring面向切面编程(一)AOP术语 添加Spring AOP的jar 参考:Maven添加Spring jar 还需添加: 创建User类: package com.user; public class User { private String username; private String password; public String getUsernam

spring中面向切面编程(AOP)的个人理解

面向切面编程AOP,是spring的一大特点 Aspect切面:封装共性功能的(增强功能的)类 Advice通过:切面类中封装的增强功能的方法. PointCut:切入点,是一个集合的概念,该集合的表达使用一个正则表达式表达 所有核心业务对象的所有方法的前后(事务处理AOP典型的应用) JoinPoint:连接点,程序中需要加入advice的地方,而且正在执行的ponitCut 织入(Weaving):将aspect和核心业务对象,进行整合的过程. 通过特定接口实现AOp Aop通知的类型: B

Spring面向切面编程

  1.面向切面编程(AOP)的概念:把项目中需要在多处用到的功能,比如日志.安全和事物等集中到一个类中处理,而不用在每个需要用到该功能的地方显式调用.   2.术语解释:        横切关注点:分布应用于多处的功能        切面:横切关注点可以被模块化为一个类,这个类被称为一个切面        通知(advice):切面要完成的工作.Spring的通知有5种类型:before.after.after-returning.after-throwing和around这五种类型.    

Web项目中静态代理和动态代理为基础的面向切面编程AOP

本来每天更新的,我一般喜欢夜里过了十二点的时候发文章,结果难道是愚人节吗?学校的网也很有意思,断了,把我给耍了...好吧-开始今天的话题AOP.AOP太重要了,所以放到第二篇文章来谈这个话题,AOP是Spring中的重要概念.如果这个不理解Web开发中的三大框架的原理,那就呵呵了.时常听到同学和网友议论Web程序员大部分时间都是在考皮XML配置,我当时听到也是醉了,所以我要用心学习Web,其实这里面蕴含的设计模式.算法.架构思想在源码中体现的淋漓尽致啊,一个大宝库竟然视而不见可惜了.下面就一起品