Spring学习笔记(四)-AOP技术的实现-基于AspectJ注解
Spring学习笔记(四)-AOP技术的实现-基于AspectJ注解
使用框架实现AOP
- Spring:Spring框架实现AOP思想,但是Spring实现AOP的操作比较繁琐
- AspectJ:独立的框架,Eclipse基金会出品
使用AspectJ框架实现AOP
- 使用Advice表示切面执行时间
- @Before:前置通知
- @AfterRetunring:后置通知
- @Around:环绕通知
- @AfterThrowing:异常通知
- @After:最终通知
Pointcut切入点
-
指示切面执行的位置,在AspectJ中切入点表达式语法为:execution(方法的定义)
-
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
-
execution(public void com.Xxx.Xxx.UserService.doSome(String,Integer,... ...) throws Xxx)
-
通配符:
*
零个或多个任意字符..
在方法参数中表示任意多个参数,在包名后表示当前包及其子包路径+
在类名后表示当前类及其子类,在接口后表示当前接口及其实现类- execution(public * *(..)):任意公共方法
- execution(* set*('')):任意set开始的方法
-
方法修饰符可以省略
基于注解的AOP实现
-
Maven配置
-
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.1</version> </dependency>
-
拉取的jar包
-
-
-
创建切面
- 使用@Aspect注解:表示当前类是一个切面类-含有切面功能的类
-
配置通知
-
@Before
-
-
通过设置value属性配置切入点
-
-
Spring容器管理切面对象
-
<bean id="myAspect" class="com.Xxx.Xxx.MyAspect"/>
-
-
声明自动代理生成器,创建目标对象的代理对象
-
<aop:aspectj-autoproxy/>
-
Spring将会调用AspectJ框架中的功能,寻找Spring容器中所有切入点目标,将切面类中的功能加入目标对象,生成代理对象,此代理对象存在于内存中,为被修改、加强后的目标对象
-
框架自动生成目标对象的代理对象,以此不需要再自写代理,简化操作
-
-
一个切入点可以配置多个同类通知,都可执行,执行顺序不定
-
JoinPoint
-
表示通过切面加强的业务方法,在动态代理中类比于method
-
使用方法:设置为切面方法中的第一个参数 JoinPoint jp
-
作用:获取加强的方法的信息
-
包含的方法:
-
getSignature() //获取方法的签名
-
getArgs() //获取方法的参数
-
!
-
@AfterReturning
-
-
属性:
- value:配置切入点表达式
- returning:表示目标方法的返回值,与通知方法的形参名一致,Xxx ret=myService()
-
通知方法中可以使用形参接收目标方法的返回值,推荐使用Object对象参数接收,此时要在@AfterReturning中配置相应的returning属性
@Around
-
!
-
属性:value 设置切入点表达式
-
方法必须有返回值,推荐使用Object类型,表示调用目标方法期望获得的执行结果
-
方法必须有ProceedingJoinPoint参数,类比于动态代理中的method,用于执行目标方法:public interface ProceedingJoinPoint extends JoinPoint
-
在执行目标方法时将会直接调用通知方法,而不是目标方法,执行目标方法需调用:Object proceed(),类比于method.invoke()
@AfterThrowing
-
方法含有对象参数Exception
-
属性:
- value:配置切入点表达式
- throwing:值需要与通知方法的形参名一致
-
在目标抛出异常后执行,不是异常处理程序,而是监视目标方法的执行
-
try{ SomeService.doSome(..) }catch(Exception e){ myAfterThrowing(e); }
-
@After
- 在目标方法后执行,总会被执行
- 可用于释放资源
@Pointcut
- 非通知,用于配置切入点,统一管理切入点,简化操作
- 属性:value 用于配置切入点表达式
- 方法名代表切入点表达式的别名,带括号
XML配置切面
<!-- 配置切面类 -->
<bean id="logger" class="com.Xxx.utils.Logger"></bean>
<!--配置AOP-->
<aop:config>
<!--配置切面 -->
<aop:aspect id="logAdvice" ref="logger">
<!-- 配置切面功能的执行时机与切入点-->
<aop:before method="printLog" pointcut="execution(* com.itheima.service.impl.*.*(..))"></aop:before>
</aop:aspect>
</aop:config>