通知分类:
1.前置通知:在方法执行之前执行的通知
2.后置通知:在方法执行之后执行的通知(当方法遇到异常则不会执行该通知)
3.异常通知:当方法在执行期间碰到异常时执行该通知
4.环绕通知:整个方法执行的过程中执行的通知,包含前置、后置、异常和最终通知,是最强大的通知
5.最终通知:在方法执行完之后执行的通知(不论方法是否遇到异常都执行该通知)
代码实现步骤:
1.导入需要的jar包:
aopaliance.jar
aspectjweaver.jar
spring核心包
2.编写具体方法类
package com.lee.service
public class StudentService {
public void addStudent(int id) {
System.out.println("添加学生ID");
}
}
3.编写通知类
package com.lee.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* 注解方式实现AOP,在类名上面添加添加注解@Aspect
* 和实现接口不一样不需要重写方法,自己自定义方法,然后在方法名上面加上注解@Before,即成为通知方法
* @author Lee
*
*/
@Component("logAnnotation") //注解形式将类添加到SpringIOC容器,相当与<bean id="logAnnotation" class="com.lee.aop.LogAspectAnnotation"></bean>
@Aspect
public class LogAspectAnnotation {
//前置通知
@Before("execution(public void com.lee.service.StudentService.addStudent(int))")
public void before(JoinPoint jp) {
System.out.println("前置通知");
}
//后置通知
@AfterReturning(pointcut = "execution(public void com.lee.service.StudentService.addStudent(int))",returning = "returningValue")
public void after(JoinPoint jp,Object returningValue) {//使用对象JionPoint获取参数,使用returningValue获取返回值,returningValue需要在注解中声明
System.out.println("后置通知,目标对象" + jp.getTarget() + ",目标方法:" + jp.getSignature().getName()+ ",返回值长度:" + jp.getArgs().length + ",返回值:" + returningValue);
}
//异常通知
@AfterThrowing("execution(public void com.lee.service.StudentService.addStudent(int))")
public void exception() {
System.out.println("异常通知");
}
//最终通知
@After("execution(public void com.lee.service.StudentService.addStudent(int))")
public void myFinally() {
System.out.println("最终通知");
}
//环绕通知使用ProceedingJoinPoint用来获取参数
@Around("execution(public void com.lee.service.StudentService.addStudent(int))")
public void around(ProceedingJoinPoint jp) {
try {
//前置通知
System.out.println("环绕前置通知");
jp.proceed();//执行方法
//后置通知
System.out.println("环绕后置通知");
}catch(Throwable e) {
//异常通知
System.out.println("环绕异常通知");
}finally {
//最终通知
System.out.println("环绕最终通知");
}
}
}
4.applicationContext.xml配置
<!-- 开启注解对AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 把注解所在的类的包放在扫描器中 -->
<context:component-scan base-package="com.lee.aop"></context:component-scan>
5.表达式execution示例
举例 |
含义 |
public boolean addStudent(com.lee.entity.Student)) |
所有返回类型为boolean、参数类型为com.lee.entity.Student的addStudent()方法。 |
public boolean com.lee.service.StudentService. addStudent(com.lee.entity.Student) |
com.lee.service.StudentService类(或接口)中的addStudent()方法,并且返回类型是boolean、参数类型是com.lee.entity.Student |
public * addStudent(com.lee.entity.Student) |
“*”代表任意返回类型 |
public void *( com.lee.entity.Student) |
“*”代表任意方法名 |
public void addStudent(..) |
“..”代表任意参数列表 |
* com.lee.service.*.*(..) |
com.lee.service.StudentService包中,包含的所有方法(不包含子包中的方法) |
* com.lee.service..*.*(..) |
com.lee.service.IStudentService包中,包含的所有方法(包含子包中的方法) |