AOP 中的声明主要有两种基于XML和基于Annotation
之前的为借助xml ,现在介绍一下借助注解的方式,修改之前的小项目
常见五种通知类型
org.springframework.aop.MethodBeforeAdvice(前置通知) 在方法之前自动执行的通知称为前置通知,可以应用于权限管理等功能。
org.springframework.aop.AfterReturningAdvice(后置通知) 在方法之后自动执行的通知称为后置通知,可以应用于关闭流、上传文件、删除临时文件等功能。
org.aopalliance.intercept.MethodInterceptor(环绕通知) 在方法前后自动执行的通知称为环绕通知,可以应用于日志、事务管理等功能。
org.springframework.aop.ThrowsAdvice(异常通知) 在方法抛出异常时自动执行的通知称为异常通知,可以应用于处理异常记录日志等功能。
org.springframework.aop.IntroductionInterceptor(引介通知) 在目标类中添加一些新的方法和属性,可以应用于修改旧版本程序(增强类)。
常见注解
@Aspect:作用是把当前类标识为一个切面供容器读取
@Around:环绕增强,相当于MethodInterceptor
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
@Pointcut:Pointcut是植入Advice的触发条件。每个Pointcut的定义包括2部分,一是表达式,二是方法签名。方法签名必须是 public及void型。可以将Pointcut中的方法看作是一个被Advice引用的助记符,因为表达式不直观,因此我们可以通过方法签名的方式为 此表达式命名。因此Pointcut中的方法只需要方法签名,而不需要在方法体内编写实际代码。
@Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterThrowing:异常抛出增强,相当于ThrowsAdvice
@After: final增强,不管是抛出异常或者正常退出都会执行使用pointcut代码
@DeclareParents 用于定义引介通知,相当于IntroductionInterceptor(不要求掌握)。
一、借助注解实现之前小例子
1、对bean 的注解 ,借助@Component
将applicationContext.xml 中的
<bean name="ser_stu" class="com.obge.service.StudentService"></bean> <bean name="logAspect" class="com.obge.aspect.LogAspect"/>
变成如下,表示扫描aspect 和service 两个包,定位业务层和切面类
<context:component-scan base-package="com.obge.aspect"/> <context:component-scan base-package="com.obge.service"/>
在相关包中的类上加上Component 注解
2、对切面的注解,借助 @Aspect 和 @Around
@Aspect 注解表示这是一个切面
@Around(value = "execution(* com.obge.service.StudentService.*(..))") 表示对com.obge.service.StudentService这个类中的所有方法进行切面操作
将applicationContext.xml 中的
<aop:config> <!-- * 返回任意类型 (..) 参数是任意数量和类型 --> <aop:pointcut id="alog_pointcut" expression="execution(* com.obge.service.StudentService.*(..))"/> <aop:aspect id="asp_log" ref="log_Aspect"> <aop:around pointcut-ref="alog_pointcut" method="log"/> </aop:aspect> </aop:config>
替换为,找到注解的切面类,进行切面配置
<aop:aspectj-autoproxy/>
切面类中进行如下修改:
package com.obge.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; //bean 对象 @Component("log_Aspect") //一个切面类 @Aspect public class LogAspect { //将这个方法 与 StudentService 类中的方法进行编制 @Around(value="execution(* com.obge.service.StudentService.*(..))") public Object log(ProceedingJoinPoint proJoinPoint) throws Throwable { System.out.println("开始记录日志:"+proJoinPoint.getSignature()); Object obj = proJoinPoint.proceed(); System.out.println("日志结束:"+proJoinPoint.getSignature().getName()); return obj; } }