aop思想可以很好的幫助我們實現代碼的解耦,比如我們之前提到的,將日誌代碼與業務層代碼完全獨立,通過spring aop的代理類進行整合。在切面類中,我們也能夠通過spring提供的接口,很好的獲取原切入點的相關信息。
首先,我們還是從代碼着手
業務層代碼StudentServiceImpl
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Override
public int addStudent(Student student) throws Exception {
System.out.println("addStudent...業務層代碼執行...");
return 1;
}
@Override
public int deleteStudent(Integer id) throws Exception{
System.out.println("deleteStudent...業務層代碼執行...");
int i = 1/0;
return 0;
}
}
切面類StudentServiceLogger
@Aspect
@Component
public class StudentServiceLogger {
@Before("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
public void doBefore(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName+"方法執行前...");
System.out.println("參數爲:"+ Arrays.asList(args));
}
@After("execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )")
public void doAfter(JoinPoint joinPoint){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName+"方法執行後...");
}
@AfterReturning(value = "execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )" , returning = "returning")
public void doReturn(JoinPoint joinPoint,Object returning){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName+"方法返回,返回值爲:"+returning);
}
@AfterThrowing(value = "execution(* com.wuwl.service.impl.StudentServiceImpl.*(..) )",throwing = "ex")
public void doThrow(JoinPoint joinPoint,Exception ex){
String methodName = joinPoint.getSignature().getName();
System.out.println(methodName+"方法異常,異常信息爲:"+ex.getMessage());
}
}
測試類AopTest
public class AopTest {
ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
@Test
public void test1() throws Exception {
StudentService studentService = ac.getBean("studentService",StudentService.class);
studentService.addStudent(new Student());
System.out.println("==================割===============");
studentService.deleteStudent(1);
}
}
最後是日誌輸出結果
addStudent方法執行前...
參數爲:[com.wuwl.domain.Student@7e5c856f]
addStudent...業務層代碼執行...
addStudent方法執行後...
addStudent方法返回,返回值爲:1
==================割===============
deleteStudent方法執行前...
參數爲:[1]
deleteStudent...業務層代碼執行...
deleteStudent方法執行後...
deleteStudent方法異常,異常信息爲:/ by zero
關於切入點方法的相關信息,spring很好的封裝在了org.aspectj.lang.JoinPoint
接口中,這裏需要注意的是,在org.aopalliance.intercept
包下,也有這樣命名的一個接口,千萬不要搞錯了。
joinPoint.getArgs()
方法可以返回切入方法的參數信息,返回值爲一個數組,遍歷即可獲取;joinPoint.getSignature()
方法的返回值爲方法簽名,簽名接口中就包括方法名之類的信息。
如果需要在通知方法中獲取切入方法的返回值,或者異常信息,則需要使用到對應註解的對應屬性才行。點開@AfterReturning註解可以看到一個String returning() default "";
屬性,在通知方法中添加返回值參數,然後再註解中聲明該參數爲切入方法的返回值即可,操作方法可參考上面的代碼。同理可以,使用@AfterThrowing註解的String throwing() default "";
屬性,可以獲取到切入方法拋出的異常信息。