需求:当系统发生异常后,将异常信息写入指定日志文件中。(基于Spring AOP实现)
编写一个组件(封装将e写入日志文件逻辑)
添加Spring AOP配置,将组件作用到所有Controller上(在不修改原有组件代码情况下,可以为组件追加新功能)
Spring AOP介绍
Aspect Oriented Programming
面向方面(切面)编程
Object Oriented Programming
面向对象编程
AOP是以OOP为基础,区别在于侧重点不同。
OOP侧重点在于对象封装。
AOP侧重点在于某个共通逻辑的提取。
AOP可以将共通逻辑和传统业务逻辑隔离,降低业务之间的耦合度。
AOP优势:可以将共通业务逻辑和传统业务逻辑隔离,之后单独封装成独立组件,最后通过AOP配置建立作用关系。
AOP相关概念
切面(Aspect)–要追加的共通处理
在某个时刻和阶段共通调用的业务逻辑。(共通性,调用时机相同)
切入点(Pointcut)–要切入的目标(给谁追加共通处理)
指的是用于指定目标组件及方法,Spring提供了几种切入点表达式。
名称限定表达式
excution(修饰符 返回类型 方法名(参数列表) 异常类型)
//匹配所有已User结尾的方法
excution(* *User(..))
//匹配UserService类中addUser方法
excution(* com.qman.UserService.addUser(..))
//匹配UserService类中的所有方法
excution(* com.qman.UserService.*(..))
//匹配com.qman包下的所有类所有方法
excution(* com.qman..(..))
//匹配com.qman包及子包所有类所有方法
excution(* com.qman...(..))
类型限定表达式
//匹配UserService类中所有方法
within(com.qman.UserService)
//匹配com.qman包下所有类所有方法
within(com.qman.*)
//匹配com.qman包及子包中所有类所有方法
within(com.qman..*)
通知(Advice)–啥时候调共通
用于指定切入时机。意思是切面和目标的作用的时机
Spring提供了以下5种通知
try{
前置通知–>调用切面 @Before
//目标方法
后置通知–>调用切面 @AfterReturning
}catch(Exception e){
异常通知–>调用切面 @AfterThrowing
}finally{
最终通知–>调用切面 @After
}
环绕通知 = 前置+后置 @Around
-进入每一个Controller要先打一个桩
切面:打桩
切入点:利用表达式指定Controller.execute方法
通知:在execute方法之前调用切面
Spring AOP实现原理
Spring AOP是采用动态代理设计模式实现的。在使用AOP之后,在Spring容器会根据目标组件,动态生成一个新的组件类型(系统产生新的类),该类被称为”动态代理类”。
-动态代理类:重写了原有目标组建的业务方法,在重写方法中调用切面功能和原目标组件功能。(用次类重写原有的类并实现事务切面组件功能)
UserServiceImpl(登陆检查)
–>动态代理类(调用UserServiceImpl+事务切面组件功能)
–>对外提供服务
Spring使用的动态代理技术有两种:
-采用JDK API java.reflect.Proxy生成
默认适用于有接口的目标组件
-采用CGLIB技术生成
默认适用于没有接口的目标组件