.1 AOP概念
AOP(Aspect-Oriented Programming,面向切面编程),简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或业务封装起来,再把封装功能整合到业务中。
AOP的核心思想就是“将应用程序中的业务逻辑同对其提供支持的通用服务进行分离"
好处:
1,便于减少系统的重复代码
2,降低模块间的耦合度
3,有利于未来的可操作性和可维护性。
例如:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。
3.2 AOP入门示例
需求:在服务层用AOP给所有方法(增删改)添加统一日志服务(谁什么时间操作了哪个对象的哪个方法。。。。)
1,添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<!--aop包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.8</version>
</dependency>
实现类
util
spring_aop.xml
测试类
1,切面(Aspect)
切点和增强组成,被抽取的公共模块 如:将日志记录,性能统计,安全控制,事务处理,异常处理等等
2,增强(Advice)又叫通知
通知是切面的具体实现,是放置“切面代码”的类。在不修改原有代码的前提下,为某一个对象增加新的功能,增加的新功能就是增强。切面在某个具体的连接点采取的行为或行动称为通知。
3,切入点(Pointcut)
多个连接点组成一个切入点,可以使用切入点表达式来表示,AOP通过切点定位到特定的连接点。
切入点表达式:
任意公共方法的执行:
execution(public * *(..))
任何一个名字以“set”开始的方法的执行:
execution(* set*(..))
AccountService接口定义的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
在service包中定义的任意方法的执行:
execution(* com.xyz.service.*.*(..))
在service包或其子包中定义的任意方法的执行:
execution(* com.xyz.service..*.*(..))
等等
4,连接点(Join point)
程序执行过程中某个特定的点,连接点总是代表某个方法执行的特定位置。类开始初始化前、类初始化后、类的某个方法调用前、类的某个方法调用后、方法抛出异常后等。
5,织入(Weaving)
织入是指将切面代码插入到目标对象的过程(或者将切入点和通知结合的过程称为织入)。
6,目标对象(Target)
包含主业务逻辑的类的对象,包含一个连接点的对象,即被拦截的对象,被代理的对象。
3.4 通知类型
Before:在目标方法被调用之前调用(前置通知)
AfterReturning:在目标方法被调用之后调用(后置通知)
Around:拦截对目标对象方法的调用(环绕通知)
After:无论目标方法是否正常运行,都一定要执行的通知(最终通知)
AfterThrowing:当目标方法抛出异常时调用(异常通知)
环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别:
1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知 是不能决定的,他们只是在方法的调用前后执行通知而已,即目标方法肯定是要执行的。
2) 环绕通知可以控制返回对象,即你可以返回一个与目标对象完全不同的返回值,虽然这很危险,但是你却可以办到。而后置方法是无法办到的,因为他是在目标方法返回值后调用