1.註解配置bean.xml
除了添加context標籤,還有aop:aspectj-autoproxy標籤
<!-- 配置spring創建容器時要掃描的包-->
<context:component-scan base-package="com.jh"></context:component-scan>
<!-- 配置spring開啓註解AOP的支持 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
2. 在各層添加註解
註解模式比較簡單
service:實現類只添加了註解,其餘與XML配置一樣
/**
* 賬戶的業務層實現類
* */
@Service("accountService")
public class AccountServiceImpl implements IAccountService {
@Override
public void saveAccount() {
System.out.println("執行了保存");
}
}
service:接口無變化
utils:Logger通知類添加了註解( 仿照xml配置步驟註解 )
- @Component(“logger”) bean對象的獲取
- @Aspect 表示當前類是一個切面類
- @Pointcut(“execution(* com.jh.service.impl..(…))”) 在pt1()方法上面註解,之後的通知類型調用切入點
- @Before(“pt1()”) @AfterReturning等
package com.jh.utils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* 用於記錄日誌的工具類,它裏面提供了公共的代碼
* */
@Component("logger")
@Aspect//表示當前類是一個切面類
public class Logger {
@Pointcut("execution(* com.jh.service.impl.*.*(..))")
private void pt1(){}
/**前置通知*/
@Before("pt1()")
public void beforePrintLog(){
System.out.println("前置通知Logger類中的beforePrintLog方法開始記錄日誌了。。。");
}
/**後置通知*/
@AfterReturning("pt1()")
public void afterReturningPrintLog(){
System.out.println("後置通知Logger類中的afterReturningPrintLog方法開始記錄日誌了。。。");
}
/**異常通知*/
@AfterThrowing("pt1()")
public void afterThrowingPrintLog(){
System.out.println("異常通知Logger類中的afterThrowingPrintLog方法開始記錄日誌了。。。");
}
/**最終通知*/
@After("pt1()")
public void afterPrintLog(){
System.out.println("最終通知Logger類中的afterPrintLog方法開始記錄日誌了。。。");
}
/**環繞通知*/
@Around("pt1()")
public Object aroundPrintLog(ProceedingJoinPoint pjp){
Object rtValue=null;
try {
Object[] args=pjp.getArgs();//得到方法執行所需的參數
System.out.println("Logger類中的aroundPrintLog方法開始記錄日誌了。。。前置");
rtValue=pjp.proceed(args);//明確調用業務層方法(切入點方法)
System.out.println("Logger類中的aroundPrintLog方法開始記錄日誌了。。。後置");
return rtValue;
} catch (Throwable t) {//必須Throwable
System.out.println("Logger類中的aroundPrintLog方法開始記錄日誌了。。。異常");
throw new RuntimeException(t);
} finally {
System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。最終");
}
}
/**環繞通知結果:
* Logger類中的aroundPrintLog方法開始記錄日誌了。。。前置
* 執行了保存
* Logger類中的aroundPrintLog方法開始記錄日誌了。。。後置
* Logger類中的aroundPringLog方法開始記錄日誌了。。。最終
* */
}
測試類無變化
package com.jh.test;
import com.jh.service.IAccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**測試AOP的配置*/
public class AOPTest {
public static void main(String[] args) {
//1.獲取容器
ApplicationContext ac=new ClassPathXmlApplicationContext("bean.xml");
//2.根據id獲取service bean對象
IAccountService as=(IAccountService)ac.getBean("accountService");
//3.執行方法
as.saveAccount();
/**結果:(一般只執行3個,後置通知和異常通知不能同時存在)
前置通知Logger類中的beforePrintLog方法開始記錄日誌了。。。
執行了保存
最終通知Logger類中的afterPrintLog方法開始記錄日誌了。。。
後置通知Logger類中的afterReturningPrintLog方法開始記錄日誌了。。。
* */
}
}