1. 程式人生 > 實用技巧 >SpringBoot @Aspect 面向切面程式設計的使用

SpringBoot @Aspect 面向切面程式設計的使用

AOP為Aspect Oriented Programming的縮寫,意為:面向切面程式設計,通過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術.AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內容,是函數語言程式設計的一種衍生範型。

在spring AOP中業務邏輯僅僅只關注業務本身,將日誌記錄,效能統計,安全控制,事務處理,異常處理等程式碼從業務邏輯程式碼中劃分出來,通過對這些行為的分離,我們希望可以將它們獨立到非指導業務邏輯的方法中,進而改變這些行為的時候不影響業務邏輯的程式碼。

註解:

@Aspect:作用是把當前類標識為一個切面供容器讀取
 
@Pointcut
:Pointcut是植入Advice的觸發條件。每個Pointcut的定義包括2部分,一是表示式,二是方法簽名。方法簽名必須是 public及void型。可以將Pointcut中的方法看作是一個被Advice引用的助記符,因為表示式不直觀,因此我們可以通過方法簽名的方式為 此表示式命名。因此Pointcut中的方法只需要方法簽名,而不需要在方法體內編寫實際程式碼。 @Around:環繞增強,相當於MethodInterceptor @AfterReturning:後置增強,相當於AfterReturningAdvice,方法正常退出時執行 @Before:標識一個前置增強方法,相當於BeforeAdvice的功能,相似功能的還有 @AfterThrowing
:異常丟擲增強,相當於ThrowsAdvice @After: final增強,不管是丟擲異常或者正常退出都會執行

@Aspect
@Component
public class BrokerAspect {

    private Logger logger = LoggerFactory.getLogger(BrokerAspect.class);

    /**
     * 定義切入點,切入點為cn.com.controller中的所有函式
     *通過@Pointcut註解宣告頻繁使用的切點表示式
     */
    @Pointcut("execution(public * cn.com.controller.*.*(..)))")
    
public void BrokerAspect(){ } /** * @description 在連線點執行之前執行的通知 */ @Before("BrokerAspect()") public void doBeforeGame(JoinPoint joinPoint){ // 接收到請求,記錄請求內容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 記錄下請求內容 logger.info("URL : " + request.getRequestURL().toString()); logger.info("HTTP_METHOD : " + request.getMethod()); logger.info("IP : " + request.getRemoteAddr()); logger.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); logger.info("ARGS : " + Arrays.toString(joinPoint.getArgs())); } }

一些常見的切入點的例子
execution(public * * (. .)) 任意公共方法被執行時,執行切入點函式。
execution( * set* (. .)) 任何以一個“set”開始的方法被執行時,執行切入點函式。
execution( * com.demo.service.AccountService.* (. .)) 當介面AccountService 中的任意方法被執行時,執行切入點函式。
execution( * com.demo.service..(. .)) 當service 包中的任意方法被執行時,執行切入點函式。

within(com.demo.service.) 在service 包裡的任意連線點。

within(com.demo.service. .) 在service 包或子包的任意連線點。

this(com.demo.service.AccountService) 實現了AccountService 介面的代理物件的任意連線點。
target(com.demo.service.AccountService) 實現了AccountService 介面的目標物件的任意連線點。
args(java.io.Serializable) 任何一個只接受一個引數,且在執行時傳入引數實現了 Serializable 介面的連線點

參考連結:https://blog.51cto.com/snowtiger/2053668

     https://blog.csdn.net/fz13768884254/article/details/83538709