基于注解实现AOP
新建LogAnnotation.java通知类
package com.itheima.aop;
//@Component("logAnnotation") //注解将本类加入Spring容器中
@Aspect //注解AOP
public class LogAnnotation{
//注解前置通知
@Before("execution(public void addPerson(..))")//如果没有返回值则则可以直接写切入点
public void myBefore(JoinPoint joinPoint){
System.out.println("注解-----------------前置通知!" + "目标对象:" + joinPoint.getTarget() + " 方法名:" + joinPoint.getSignature().getName() + " 参数个数:" + joinPoint.getArgs().length + " 参数列表:" + Arrays.toString(joinPoint.getArgs()));
}
// 注解后置通知
@After(pointcut="execution(public void addPerson(..))",returning = "returningValue")//有返回值则需要指定
public void myAfter(JoinPoint joinPoint,Object returningValue){
//returningValue是返回值,固定写法,注意如果返回值是void则会报错
System.out.println("注解-----------------后置通知!" + "目标对象:" + joinPoint.getTarget() + " 方法名:" + joinPoint.getSignature().getName() + " 参数个数:" + joinPoint.getArgs().length + " 参数列表:" + Arrays.toString(joinPoint.getArgs()) + " 返回值:" + returningValue);
}
// 环绕通知
@Around("execution(public void addPerson(..))")
public void myException(ProceedingJoinPoint proceedingJoinPoint){
try {
//前置通知
System.out.println("注解环绕-----------------前置通知!");
proceedingJoinPoint.proceed();
//后置通知
System.out.println("注解环绕-----------------后置通知!");
} catch (Throwable e) {
//异常通知
System.out.println("注解环绕-----------------异常通知!");
}finally {
//最终通知
System.out.println("注解环绕-----------------最终通知!");
}
}
//最终通知
@After("execution(public void addPerson(..))")
public void myAfter(){
System.out.println("注解最终通知!");
}
//异常通知,捕获指定异常
@AfterThrowing(pointcut = "execution(public void addPerson(..))" ,throwing = "e")
public void myException(JoinPoint joinPoint,NullPointerException e){
//捕获指定NullPointerException 异常
System.out.println("注解异常通知!异常:" + e);
}
}
开启注解对AOP的支持
配置扫描器
<context:component-scan base-package="com.itheima.aop"/>
运行结果
基于配置(Schema)形式实现AOP
通过配置将一个普通类转为AOP
新建通知类:LogSchema.java
package com.itheima.aop;
import org.aspectj.lang.JoinPoint;
import java.util.Arrays;
public class LogSchema {
//配置前置通知
public void before(JoinPoint joinPoint) {
System.out.println("配置Schema形式的---前置通知!" + "目标对象:" + joinPoint.getTarget() + " 方法名:" + joinPoint.getSignature().getName() + " 参数个数:" + joinPoint.getArgs().length + " 参数列表:" + Arrays.toString(joinPoint.getArgs()));
}
}
<!-- 配置方式实现AOP-->
<!-- 将类通知类纳入IOC容器-->
<bean id="logSchema" class="com.itheima.aop.LogSchema"/>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(public void com.itheima.service.PersonServiceImpl.addPerson(com.itheima.entity.Person))"/>
<aop:aspect ref="logSchema">
<!--连接线-->
<aop:before method="before" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
解释: