自定義注解實現(spring aop)


1.基本概念

1.1 aop

即面向切面編程,優點是耦合性低,能使業務處理和切面處理分開開發,擴展和修改方面,當引入了注解方式時,使用起來更加方便。

1.2 應用場景

打日志、分析代碼執行時間、權限控制、事務處理、訪問頻率控制、異常處理等等。

1.3 主要概念

幾乎所有涉及aop的地方都會對這些概念進行說明,這里只說說個人的理解,可先了解一下基本概念,然后看完例子之后回頭結合這些概念,才能更深刻的理解。

Aspect:關注點的模塊化。類似於類聲明,包含PointCut和對應的Advice。在Spring AOP中被定義為接口@Aspect,作用於TYPE(類、接口、方法、enum)

JoinPoint:程序執行過程中明確的點,如方法的調用或特定的異常被拋出。常用的是getArgs()用來獲取參數,getTarget()獲得目標對象。

Pointcut:表示一組JoinPoint,這些JoinPoint或是通過邏輯關系組合起來,或是通過通配、正則表達式等方式集中起來,它定義了相應的 Advice 將要發生的地方。 在Spring AOP中被定義為作用於METHOD上的接口@Pointcut

Introduction:添加方法或字段到被通知的類。

Advice: 定義了在 pointcut 里面定義的程序點具體要做的操作,它通過 before、after 和 around 來區別是在每個JoinPoint之前、之后還是代替執行的代碼。

 

Target Object:包含連接點的對象。也被稱作被通知或被代理對象。POJO

Weaving:組裝方面來創建一個被通知對象。 

2.原理淺析

2.1 UML

對於AOP的理解,首先需要看下UML圖,大致有個概念。

2.2 配置文件方式實現aop

如果需要理解一樣東西,首先要會用,再此基礎上理解才會更加深刻。這里給出一個例子,例子原文http://www.cnblogs.com/hongwz/p/5764917.html

 

 

這個例子相對比較容易理解一點,TimeHandler是Aspect,"execution(* com.bird.service.impl.PersonServiceBean.*(..))"是PointCut,before/after 是Advice,helloWordImpl1/helloWordImpl2是目標對象。

 

 

3. 注解實現

3.1 示例

aop實現一般是針對現有代碼基礎上做一些其他操作,例如下面代碼所示。

這里一切以IOC為基礎

@Aspect修飾類,說明該類是切面關注的抽象,即針對切面目標對象要做什么操作。

@Pointcut針對Spring MVC的RequestMapping和ResponseBody注解(@Iterface)。

@Before、@After、@AfterReturing等針對目標對象相應動作(before、after等)做出相應的操作。

JoinPoint joint 可以獲取目標對象的參數。Object[] argcs= joinPoint.getArgs(); argcs類似於main方法的參數數組,只不過這里需要類型轉換把Object轉換成相應的type。

3.2 實現

這里以限制訪問頻率舉例。在Controller上加上注解,設置參數就可以實現控制用戶的某個時間段內的訪問次數。用到Redis,如果沒有Redis,可以用LocalThread代替。

1. 自定義注解

  

@Retention(RetentionPolicy.RUNTIME) :

這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用。此外RetentionPolicy.SOURCE —— 這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略;RetentionPolicy.CLASS —— 這種類型的Annotations編譯時被保留,在class文件中存在,但JVM將會忽略

@Target

定義注解的作用目標。@Target(ElementType.FIELD)表示該注解可以作用於類或者方法上

@Order

當有多個切面時,Order決定先執行哪個后執行哪個。如果不加Order則默認按照注解標注的先后順序執行。@Order(Ordered.HIGHEST_PRECEDENCE)表示最高優先級。

 2.自定義切面

 

 如圖所示@Aspect表示了該類是切面。

@within:用於匹配所以持有指定注解類型內的方法;@annotation(limit) 是匹配含有limit注解的方法。

@Before("within(@org.springframework.stereotype.Controller *) && @annotation(limit)") 表示對含有SpringMVC的Controller注解下面的方法 且含有 注解limit的方法有效。

jointPoint獲取HttpServletRequest(被修飾的方法需要有HttpServletRequest參數)

redis/Jedis不熟悉的只需要了解下兩個方法就行:incr方法表示為key值加1,如果key不存在則新建一個key值,並初始化為1。expire表示經過time時間后key會消失。

邏輯是某個Ip地址對某個接口url,在過期時間內如果超過規定的次數就會拋出訪問頻率過高的異常。

3.在需要修飾的對象上加注解使用

 

4.如果注解沒有生效,檢查下spring配置文件是否配置了aop


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM