Spring学习笔记——AOP



AOP

1.OOP开发思路

2.AOP简介

2.1AOP开发思路

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2.2AOP概述

AOP:面向切面编程。它是一种编程范式。指导开发者如何组织程序结构。

AOP弥补了oop的不足,基于oop基础之上进行横向的开发。

OOP的程序开发以类为主题模型,一切围绕着对象进行。

AOP程序主要关注的是OOP开发中的一些共性功能。一切都是围绕着共性功能进行。

2.3.AOP的作用

AOP可以从各个行业的标准化,规范化开始入手。一步一步的将所有的共性功能逐一开发,最终以功能组合的方式完成业务模块甚至整个程序的开发。

目标:将软件开发由手动制作走向半自动化/全自动化阶段。实现"插拔式组件体系"。

2.4 AOP优点

提高了代码的复用性

业务代码更简洁

业务代码维护更加方便

3.AOP的入门程序

3.1 AOP相关概念

JoinPoint:连接点。就是所有的方法

Pointcut:切入点。就是需要挖掉共性代码的方法

Advice:通知。就是共性功能。最终以方法的形式存在

Aspect:切面。共性功能和所挖位置的对应关系

Target:目标对象。就是挖掉共性功能后的类所产生的对象。这种对象无法完成最终工作

Weaving:织入。讲挖掉功能的回调的动态过程

Proxy:代理。目标对象无法直接完成工作。需要对其进行功能回填。通过创建目标对象的代理对象实现

3.2 AOP入门开发思路

开发阶段:

正常的功能开发

挖出功能开发制作成通知。挖掉代码后的方法成为切入点的方法

在配置文件中声明切入点

在配置文件中声明切入点和通知的关系(切面)

运行阶段:

Spring容器加载配置,监控所有配置切入点方法的执行

当监控到切入点方法被运行,使用代理机制动态创建目标对象的代理对象。根据通知类型,在代理对象的对应位置将通知对应的功能(挖出的共性代码)织入。最终完成完整的代码逻辑并运行。

3.3 AOP入门制作
3.3.1 创建项目导入依赖
3.3.2 抽取共性代码
public class UserAdvice {
	
	public void opentx() {
		System.out.println("开启了事务");
	}
	
	public void closetxAndLog() {
		System.out.println("关闭了事务");
		System.out.println("记录了日志");
	}
}
3.3.3 配置AOP的配置

注意:首先确保配置文件中存在aop的命名空间

 <beans>
 <!-- 把通知和目标对象加载到容器中 -->
    <bean id="userService" class="com.lxk.service.UserService"></bean>
	<bean id="userAdvice" class="com.lxk.advice.UserAdvice"></bean>
	<!-- aop的配置 -->
	<aop:config>
		<!-- 配置切入点 --> 
		<aop:pointcut expression="execution(* *..*(..))" id="pt"/>
		<!-- 配置切面 -->
		<aop:aspect ref="userAdvice">
			<aop:before method="opentx" pointcut-ref="pt"/>
			<aop:after method="closetxAndLog" pointcut-ref="pt"/>
		</aop:aspect>
	</aop:config>
</beans>
3.4 配置详解
3.4.1 AOP配置

名称:aop:config

作用:代表设置AOP

说明:一个Spring中可以配置多个AOP

3.4.2 切入点

名称:aop:pointcut

作用:配置切入点

属性:expression:切入点表达式

说明:一个aop:config标签内可以配置多个aop:pointcut标签。而且这个标签可以配置在aop:aspect标签内

3.4.3 切面

名称:aop:aspect

作用:配置具体额AOP通知对应的切入点

3.5 通知类型

AOP中的通知类型一共5种。

前置通知:aop:before

​ 简介:原始方法执行前执行。如果出现异常,阻止原始方法的执行

​ 应用场景:数据校验

后置通知:aop:after

​ 简介:原始方式执行后执行。无论原始方法是否出现异常都将执行此通知

​ 应用场景:现场清理

返回后通知:aop:after-returning

​ 简介:原始方法执行完毕并且返回结果后执行。如果原始方法抛出异常则无法执行。

​ 引用场景:返回值的相关数据处理

抛出异常后通知:aop:after-throwing

​ 简介:原始方法抛出异常后执行。如果没有异常则无法执行

​ 应用场景:对原始方法中出现的异常信息进行处理

环绕通知:aop:around

​ 简介:在原始方法执行前后都可以执行

​ 注意:环绕通知是在原生方法的前后添加功能,在环绕通知中存在对原始方法的显式调用

​ 方法必须设定Object类型的返回值。否则会拦截原始方法的返回。如果原始方法返回值类型为void,通知方法也可以设置成void。最终返回null。

​ 使用proceed()调用原始方法时,由于无法预知原方法运行是否会出现异常,所以强制抛出异常对象,原始方法可能出现异常信息。

3.6切入点表达式

切入点表达式最终描述的就是某个方法。切入点表达式是一个快速匹配方法描述的通配格式。类似于正则。

格式:关键字(访问修饰符 返回值 包名.类名.方法名(参数)异常名)

关键字:描述表达式的匹配模式。execution:匹配执行指定方法

通配符:*:单个独立的任意符号。可以单独出现,也可以当成前缀和后缀出现。

​ …:多个连续的任意符号。一般用于简化包名和参数的书写。

​ +:用于匹配子类型

范例:

execution(* *(..))
execution(* *..*(..))
execution(* *..*.*(..))
//前三个等价
execution(public * *..*.*(..))
execution(public int *..*(..))
execution(public void com..*.*(..))
execution(public void com..*.find*(..))
execution(public void com..*.*(*,int))
execution(public void com..*.findAll())
execution(public void com.lxk.service.*.*())

4.AOP注解

4.1开启AOP注解
<!-- 支持AOP的注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>   
<context:component-scan base-package="com.lxk"></context:component-scan>
4.2 注解开发
@Component
@Aspect
public class UserAdvice {
	
	@Pointcut("execution(* *..*(..))")
	public void pt() {}
	
	@Before(value="pt()")
	public void opentx() {
		System.out.println("开启了事务");
	}
	@After(value="pt()")
	public void closetxAndLog() {
		System.out.println("关闭了事务");
		System.out.println("记录了日志");
	}
	@AfterThrowing(value="pt()",throwing="yy")
	public void afterThrowing(Throwable yy) {
		System.out.println("异常通知");
	}
	@AfterReturning("pt()")
	public void afterReturning() {
		System.out.println("返回后通知");
	}
	@Around("pt()")
	public Object around(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("环绕前");
		//调用原始方法
		Object proceed = pjp.proceed();
		System.out.println("环绕后");
		return proceed;
	}
}

5.AOP注解驱动

使用@EnableAspectJAutoProxy。具体用法和Spring IOC的注解驱动开发一样。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值