java实训笔记_Spring的AOP

1 前言

上一篇写了Spring的xml注入
这一篇写一下Spring的AOP

2 本篇内容

AOP简述、AOP、AOP实现方式以及Aspectj的使用。

3 AOP简述

AOP,Aspect Oriented Programming,意思是面向切面编程,是Spring的一个主要特性,通过代理机制来实现。

4 AOP

4.1 AOP名词

首先了解一下一些名词。

  • target 目标类,即被代理的类
  • JoinPoint 连接点,即可能被拦截到的方法
  • PointCut 切入点,即被增强的连接点
  • advice 通知/增强,即想要加入的功能
  • weaving 织入,把advice加入到target创建新的代理对象proxy的过程
  • Aspect 切面,切入点与通知advice结合的地方(是一个类)

4.2 AOP理解

AOP我理解为 通过代理的方式给一个类加上一些功能,并将加上功能以后的类返回用户。

5 Aspectj实现AOP

5.1 AOP底层实现方式

AOP底层有两种实现:一种是使用JDK代理实现的,一种是通过Cglib实现的,JDK代理通过接口+实现类实现,Cglib代理通过实现类实现。但是两种实现比较麻烦,可以引入Aspectj包来简化实现AOP操作的过程。

5.2 导入Aspectj包、引入AOP

5.2.1 pom导入Aspectj依赖

		<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.9.5</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/aspectj/aspectjrt -->
		<dependency>
			<groupId>aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>1.5.4</version>
		</dependency>

5.2.2 引入Aop

引入aop后的beans声明如下。

<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.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">

5.3 Aspectj通知类型

Aspectj有五种通知类型

  • before 前置通知
  • after 最终通知
  • afterReturning 后置通知(常规数据处理)
  • afterThrowing 抛出异常通知(包装异常信息)
  • around 环绕通知(方法执行前后都会执行,必须手动执行方法,可以做很多事情)

5.4 使用Aspectj

5.4.1 编写类

需要写目标接口Person,目标类PersonImpl,切面实现类MyAspectj,这里仅贴出MyAspectj的代码

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspectj {
	public void myBefore(JoinPoint joinPoint) {
		System.out.println("前置通知:"+ joinPoint.getSignature().getName());
	}
	
	public void myAfterReturning(JoinPoint joinPoint,Object ret) {
		System.out.println("后置通知:"+ joinPoint.getSignature().getName()+"----->"+ret);
		
	}
	public void myAround(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("环绕的前");
		
		Object object=joinPoint.proceed();
		System.out.println("环绕的后");
		
	}
	public void myAfterThrowing(JoinPoint joinPoint,Throwable e) {
		System.out.println("抛出异常通知:"+e.getMessage());
	}

	public void myAfter(JoinPoint joinPoint) {
		System.out.println("最终通知:"+joinPoint.getSignature().getName());
		
	}
	
}

5.4.2 书写配置文件

使用时需要修改class参数为自己的路径。

<!-- 目标类 -->
<bean id="personTargetj" class="edu.spring.service.impl.PersonServiceImpl"></bean>
<!-- 切面类 -->
<bean id="personAspectj" class="edu.spring.aspect.MyAspectj"></bean>
<aop:config>
	<!-- ref指向要包装的类 -->
	<aop:aspect ref="personAspectj">
		<!-- 通过expression确定切入点,后续通过id指定该切入点,指定的是接口中的方法 -->
		<aop:pointcut expression="execution(* edu.spring.service.*.*(..))" id="aspectjCut"/>
		<!-- 前置通知,传入参数:切入点,切入点通过poionCut-ref指定,填入切入点的id -->
		<aop:before method="myBefore" pointcut-ref="aspectjCut"/>
		<!-- 后置通知,传入参数:切入点,对象  切入点同上,对象使用returning指定,填入的值要与Aspectj实现类中的参数名一样 -->
		<aop:after-returning method="myAfterReturning" pointcut-ref="aspectjCut" returning="ret"/>
		<!-- 环绕通知,传入参数:切入点,切入点同上 -->
		<aop:around method="myAround" pointcut-ref="aspectjCut"/>
		<!-- 抛出异常通知,传入参数:切入点,异常,切入点同上,异常通过throwing指定,填入的值要与Aspectj实现类中的参数名一样 -->
		<aop:after-throwing method="myAfterThrowing" pointcut-ref="aspectjCut" throwing="e"/>
		<!-- 最终通知,传入参数:切入点,切入点同上 -->
		<aop:after method="myAfter" pointcut-ref="aspectjCut"/>
	</aop:aspect>
</aop:config>

5.4.3 运行结果

从结果可以看出各个通知的执行顺序,因为没有报错所以没有抛出异常通知。
顺序为 前置–>环绕的前–>方法执行–>最终通知–>环绕的后–>后置通知
在这里插入图片描述

5.4.4 execution表达式

在使用Aspectj的过程中,需要通过execution表达式来确定目标方法,适当书写execution表达式可以精准定位某个方法,当然也可以写得松散一点定位一整个类里面的所有方法。
例子:execution=(* edu.spring.service.*.*(..))
在这个例子中,第一个*号是返回类型,*表示所有类型,
edu.spring.service.*.*这一段指定了路径,表示service包下的任意类、任意方法
(..)表示返回值为任意返回值。

edu.spring 表示spring包
edu.spring.. 表示spring及其子包

倒数第二个*号是类名,最后一个*号是方法名,可以用*Impl匹配以Impl结尾的,以User*匹配以User开头的。
()中不填表示无参,填入一个int表示一个整型参数,填入 int,int 表示两个整型参数。

6 结语

1.以上是我个人对于AOP的一些理解,如有不对之处还请指正。
2.csdn博客写星号要加上转义字符 \,或者写成代码块的形式。
3.有什么不明白的可以在评论区留言探讨一下。
4.会有一些红色的信息提示,暂时不做解决。

7 参考链接

1.AspectJ 通知类型及其实现
2.AspectJ通知类型

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值