SSM之Spring(三)AOP
2021/6/11 18:26:32
本文主要是介绍SSM之Spring(三)AOP,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
AOP介绍
面向切面编程(AOP)和面向对象编程(OOP)类似,也是一种编程模式。Spring AOP 是基于 AOP 编程模式的一个框架,它的使用有效减少了系统间的重复代码,达到了模块间的松耦合目的。它将业务逻辑的各个部分进行隔离,使开发人员在编写业务逻辑时可以专心于核心业务,从而提高了开发效率。AOP 采取横向抽取机制,取代了传统纵向继承体系的重复性代码,其应用主要体现在事务处理、日志管理、权限控制、异常处理等方面。
目前最流行的 AOP 框架有两个,分别为 Spring AOP 和 AspectJ。这里介绍Spring AOP的,从 Spring 2.0 开始,Spring AOP 引入了对 AspectJ 的支持。
专业术语说明
- 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
- 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
- 切点(PointCut): 可以插入增强处理的连接点。
- 切面(Aspect): 切面是通知和切点的结合。
- 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
- 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
Spring AOP 的特点
Spring 中的 AOP 是通过动态代理实现的。不同的 AOP 框架支持的连接点也有所区别,例如,AspectJ 和 JBoss,除了支持方法切点,它们还支持字段和构造器的连接点。而 Spring AOP 不能拦截对对象字段的修改,也不支持构造器连接点,我们无法在 Bean 创建时应用通知。
AOP分类
- 静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
- 动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP。
各种AOP实现方式比较
动态代理的介绍在设计模式那里会介绍,这个就不描述了。
Spring AOP使用
有两种使用方式:一种是使用Spring中的 org.springframework.aop.framework.ProxyFactoryBean 类,这个类对应的切入点和通知提供了完整的控制能力,并可以生成指定的内容,但在开发中很少使用这种方式。开发中一般使用第二种方式,Spring使用AspectJ开发AOP,这种方式主要用基于 xml 和 Annotation 来实现的,下面也主要讲的是这种实现方式。
Spring使用AspectJ开发AOP
一般使用注解方式来开发,AspectJ 允许使用注解定义切面、切入点和增强处理,而 Spring 框架则可以识别并根据这些注解生成 AOP 代理。
具体实现流程:引入spring的jar包——》创建切面类 ——》创建 Spring 配置文件(使用注解的话就不需要了)【切面类的内容就是指定在什么方法上加上什么通知】——》执行(测试)加上通知的方法
通知类型:
切入点表达式
切入点表达式主要就是来配置拦截哪些类的哪些方法,就是下面 @Pointcut 经常用到的。
语法:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
参数讲解:
- modifiers-pattern?【修饰的类型,可以不写】
- ret-type-pattern【方法返回值类型,必写】
- declaring-type-pattern?【方法声明的类型,可以不写】
- name-pattern(param-pattern)【要匹配的名称,括号里面是方法的参数】
- throws-pattern?【方法抛出的异常类型,可以不写】
符号讲解:
- ?号代表0或1,可以不写
- “*”号代表任意类型,0或多
- 方法参数为…表示为可变参数
官方案例讲解:
注解方式
首先需要在Spring配置文件中开启AOP注解方式。
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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!--扫描含com.mengma包下的所有注解--> <context:component-scan base-package="com.mengma"/> <!-- 使切面开启自动代理 --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
注解介绍:
- @Aspect:指定一个类为切面类
- @Pointcut:指定切入点表达式,通知最后增强哪些方法,注解所在的方法必须是private
- @Before:前置通知: 目标方法之前执行
- @After:后置通知:目标方法之后执行(始终执行)
- @AfterReturning:返回后通知: 执行方法结束前执行(异常不执行)
- @AfterThrowing:异常通知: 出现异常时候执行
- @Around:环绕通知: 环绕目标方法执行(常用)
使用案例:主要提供切面类的代码案例,拦截哪个类、测试代码就不提供了。
@Component//需要将bean注入到Spring容器中 @Aspect//指定为切面类 public class AOP { // 指定切入点表达式,拦截哪个类的哪些方法 @Pointcut("execution(* aa.*.*(..))") public void pt() { } @Before("pt()") public void begin() { System.out.println("开始事务"); } @After("pt()") public void close() { System.out.println("关闭事务"); } }
xml方式的实现
基于 XML 的声明式是指通过 Spring 配置文件的方式定义切面、切入点及声明通知,而所有的切面和通知都必须定义在 aop:config 元素中,下面提供一个案例:
<?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-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <!--目标类 --> <bean id="customerDao" class="com.mengma.dao.CustomerDaoImpl" /> <!--切面类 --> <bean id="myAspect" class="com.mengma.aspectj.xml.MyAspect"></bean> <!--AOP 编程 --> <aop:config> <aop:aspect ref="myAspect"> <!-- 配置切入点,通知最后增强哪些方法 --> <aop:pointcut expression="execution ( * com.mengma.dao.*.* (..))" id="myPointCut" /> <!--前置通知,关联通知 Advice和切入点PointCut --> <aop:before method="myBefore" pointeut-ref="myPointCut" /> <!--后置通知,在方法返回之后执行,就可以获得返回值returning 属性 --> <aop:after-returning method="myAfterReturning" pointcut-ref="myPointCut" returning="returnVal" /> <!--环绕通知 --> <aop:around method="myAround" pointcut-ref="myPointCut" /> <!--抛出通知:用于处理程序发生异常,可以接收当前方法产生的异常 --> <!-- *注意:如果程序没有异常,则不会执行增强 --> <!-- * throwing属性:用于设置通知第二个参数的名称,类型Throwable --> <aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointCut" throwing="e" /> <!--最终通知:无论程序发生任何事情,都将执行 --> <aop:after method="myAfter" pointcut-ref="myPointCut" /> </aop:aspect> </aop:config> </beans>
这篇关于SSM之Spring(三)AOP的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-27数据结构与算法面试题详解及练习
- 2024-12-27网络请求面试题详解与实战
- 2024-12-27数据结构和算法面试真题详解与实战教程
- 2024-12-27网络请求面试真题解析与实战教程
- 2024-12-27数据结构和算法大厂面试真题详解与实战指南
- 2024-12-27TS大厂面试真题解析与应对策略
- 2024-12-27TS大厂面试真题详解与解析
- 2024-12-27网站安全入门:如何识别和修复漏洞
- 2024-12-27SQL注入基础教程
- 2024-12-27初学者指南:理解和修复跨域漏洞