這篇“Spring AOP如何使用”文章的知識點大部分人都不太理解,所以小編給大家總結了以下內容,內容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Spring AOP如何使用”文章吧。
@Repository("userDao")
public class UserDao {
public void addUser() {
System.out.println("???? 攔截的方法 addUser 開始執行");
}
}@Aspect
@Component
public class AnnotationAspect {
// 定義切入點表達式, 使用一個返回值為 void、方法體為空的方法來命名切入點
@Pointcut("execution(* com.fairy.springmvc.aspectj.annotation.*.*(..))")
private void customPointCut(){}
// 前置通知
@Before("customPointCut()")
public void myBefore(JoinPoint joinPoint){
System.out.print("前置通知:模擬執行權限檢查..,");
System.out.print("目標類是:" + joinPoint.getTarget());
System.out.println(",被植入增強處理的目標方法為:" + joinPoint.getSignature().getName());
}
// 后置通知
@AfterReturning(value="customPointCut()")
public void myAfterReturning(JoinPoint joinPoint) {
System.out.print("后置通知:模擬記錄日志..,");
System.out.println("被植入增強處理的目標方法為:" + joinPoint.getSignature().getName());
}
/**
* 環繞通知
* ProceedingJoinPoint 是 JoinPoint的子接口,表示可執行目標方法
* 1.必須是 Object 類型的返回值
* 2.必須接收一個參數,類型為 ProceedingJoinPoint
* 3.必須 throws Throwable
*/
@Around("customPointCut()")
public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
// 開始
System.out.println("環繞開始:執行目標方法之前,模擬開啟事務..,");
// 執行當前目標方法
Object obj = proceedingJoinPoint.proceed();
// 結束
System.out.println("環繞結束:執行目標方法之后,模擬關閉事務..,");
return obj;
}
/**
* 異常通知處理
* @param joinPoint
* @param e
*/
@AfterThrowing(value="customPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
System.out.println("異常通知:出錯了" + e.getMessage());
}
// 最終通知
@After("customPointCut()")
public void myAfter(){
System.out.println("最終通知:模擬方法結束后釋放資源..");
}
}開啟@AspectJ的注解配置方式,有兩種方式
1 在 xml 文件,添加以下配置:
<!-- 啟動基于注解的聲明式 AspectJ 支持 --> <aop:aspectj-autoproxy />
2 使用了 Java 代碼風格的配置,則需使用 EnableAspectJAutoProxy 注解
示例如下
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.fairy.springmvc")
public class ApplicationConfig {
....
}public class TestCase {
@Test
public void testAnnotation() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"spring-test.xml");
// 從容器中獲得內容
UserDao userDao= (UserDao) applicationContext.getBean("userDao");
// 執行方法
userDao.addUser();
}
}運行結果如下:
環繞開始:執行目標方法之前,模擬開啟事務..,
前置通知:模擬執行權限檢查..,
目標類是:com.fairy.springmvc.aspectj.annotation.UserDao@4a699efa,
被植入增強處理的目標方法為:addUser
???? 攔截的方法 addUser 開始執行
后置通知:模擬記錄日志..,被植入增強處理的目標方法為:addUser
最終通知:模擬方法結束后釋放資源..
環繞結束:執行目標方法之后,模擬關閉事務..,
通過輸出結果看出,符合預期。
@Repository("companyDao")
public class CompanyDao {
public void addCompany() {
System.out.println("???? 真正的業務處理:add company ????");
}
public void exception() throws Exception {
throw new Exception("業務異常了");
}
}@Component("xmlAspectConfig")
public class XmlAspect {
public void printUnderscore() {
System.out.println("------------------------------------------------");
}
/**
* 在核心業務執行前執行,不能阻止核心業務的調用
* @param joinPoint
*/
public void beforeAdvice(JoinPoint joinPoint) {
printUnderscore();
System.out.println("1?? 通知:beforeAdvice 執行開始");
System.out.println(" 執行核心業務邏輯前,可以做一些前置的安全性的檢測等");
System.out.println(" 通知:beforeAdvice 執行結束");
printUnderscore();
}
/**
* 核心業務退出后,不管是正常結束還是異常退出,均執行此通知
* @param joinPoint
*/
public void afterAdvice(JoinPoint joinPoint) {
printUnderscore();
System.out.println("4?? 通知:afterAdvice 執行開始");
System.out.println(" 此處可以對返回值做進一步的處理");
System.out.println(" 通知:afterAdvice 執行結束");
}
/**
* 核心業務調用正常退出后,不管是否有返回值,只要是正常退出,都會執行此通知
* @param joinPoint
*/
public void afterReturningAdvice(JoinPoint joinPoint) {
printUnderscore();
System.out.println("2?? 通知:afterReturningAdvice 執行開始");
System.out.println(" 此處可以對返回值做進一步處理");
System.out.println(" 通知:afterReturningAdvice 執行結束");
}
/**
* 核心業務邏輯調用異常退出后,執行此通知,處理錯誤信息
* @param e
*/
public void afterThrowingAdvice(Exception e) {
printUnderscore();
System.out.println("3?? 通知:afterThrowingAdvice 執行開始");
System.out.println(" 錯誤信息:" + e.getMessage());
System.out.println(" 此處意味著,在核心業務邏輯出錯時,捕獲異常,并可以做一些日志記錄相關的操作");
}
/**
* 手動控制調用核心業務邏輯,以及調用前和調用后的處理
* @param pjp
*/
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
// 開始
System.out.println("5?? 環繞開始:執行目標方法之前");
System.out.println(" 此處可以做類似于 Before Advice 的事情");
// 調用核心邏輯,執行當前目標方法
Object obj = pjp.proceed();
// 打印下劃線
printUnderscore();
// 結束
System.out.println(" 此處可以做類似于 After Advice 的事情");
System.out.println("5?? 環繞結束:執行目標方法之后");
return obj;
}
}<!-- 基于 XML 文件的配置進行聲明,注意和 aop:aspectj-autoproxy 的區別 --> <aop:config proxy-target-class="true"> <!-- 基于 aspect 配置一個完整的切面 --> <aop:aspect id="aspectXmlConfigExample" ref="xmlAspectConfig"> <!-- 切點配置,可以配置多個切點 --> <aop:pointcut id="xmlPointCut" expression="execution(* com.fairy.springmvc.aspectj.xml.CompanyDao.*(..))"/> <aop:after-returning method="afterReturningAdvice" pointcut-ref="xmlPointCut" /> <aop:after-throwing method="afterThrowingAdvice" pointcut-ref="xmlPointCut" throwing="e"/> <aop:after method="afterAdvice" pointcut-ref="xmlPointCut" /> <aop:around method="aroundAdvice" pointcut-ref="xmlPointCut" /> <aop:before method="beforeAdvice" pointcut-ref="xmlPointCut" /> </aop:aspect> </aop:config>
注意:
值得注意的是
around與before和after的執行順序。3者的執行順序取決于在xml中的配置順序。
public class TestCase {
@Test
public void testAnnotation() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"spring-test.xml");
CompanyDao companyDao = (CompanyDao) applicationContext.getBean("companyDao");
companyDao.addCompany();
// companyDao.exception();
}
}輸出結果如下:
-------------------------------
5?? 環繞開始:執行目標方法之前
此處可以做類似于 Before Advice 的事情
------------------------------------------------
1?? 通知:beforeAdvice 執行開始
執行核心業務邏輯前,可以做一些前置的安全性的檢測等
通知:beforeAdvice 執行結束
------------------------------------------------
???? 真正的業務處理:add company ????
------------------------------------------------
2?? 通知:afterReturningAdvice 執行開始
此處可以對返回值做進一步處理
通知:afterReturningAdvice 執行結束
------------------------------------------------
4?? 通知:afterAdvice 執行開始
此處可以對返回值做進一步的處理
通知:afterAdvice 執行結束
------------------------------------------------
此處可以做類似于 After Advice 的事情
5?? 環繞結束:執行目標方法之后
結果符合預期。
以上就是關于“Spring AOP如何使用”這篇文章的內容,相信大家都有了一定的了解,希望小編分享的內容對大家有幫助,若想了解更多相關的知識內容,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。