iT邦幫忙

2021 iThome 鐵人賽

DAY 23
1

介紹

切面導向程式設計(Aspect-Oriented-Programming,AOP),它的目的在於將許多的共同方法抽離出來,與物件導向程式設計類似,但AOP 與OOP 不同的地方就在於,AOP 不用原方法呼叫共同方法,只需要指定執行共同方法的時機點即可。

實作

AOP 相關註釋都在Day 09 - Spring Boot 常用註釋(下)有詳細介紹,這邊主要是展示JoinPoint 和ProceedingJoinPoint 的使用方法。

新增依賴

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

建立切面

package com.example.iThomeIronMan.aop;

import java.util.Arrays;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

// 將當前類別標示為Spring 容器管理的類別
@Component
@Aspect
public class LoginAspect {

	private static final Logger logger = LoggerFactory.getLogger(LoginAspect.class);

	// 設定切入點
	@Pointcut("execution(* com.example.iThomeIronMan.controller..*(..))")
  public void pointcut() {
  }

  @Before("pointcut()")
  public void before(JoinPoint joinPoint) {
      System.out.println("=====Before advice starts=====");
      
	  	logger.info("訪問 " + joinPoint.getSignature().getName());
      Arrays.stream(joinPoint.getArgs()).forEach(System.out::println);
      
      System.out.println("=====Before advice ends=====");
  }

  @Around("pointcut()")
  public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
      System.out.println("=====Around advice starts=====");

      long startTime = System.currentTimeMillis();

			// 呼叫proceed() 方法開始執行原方法
      Object result = joinPoint.proceed();
      long spentTime = System.currentTimeMillis() - startTime;
	  	logger.info("訪問 " + joinPoint.getSignature().getName() + " Time spent: " + spentTime);
      
      System.out.println("=====Around advice ends=====");

      return result;    	
  }
  
  @After("pointcut()")
  public void after(JoinPoint joinPoint) {
      System.out.println("=====After advice starts=====");

	  	logger.info("訪問 /" + joinPoint.getSignature().getName());
      Arrays.stream(joinPoint.getArgs()).forEach(System.out::println);
      
      System.out.println("=====After advice ends=====");
  }
   
    
}

參考網址

AOP 觀念與術語
【Spring Boot】第20課-切面導向程式設計(AOP)


上一篇
Day 22 - Spring Boot & Interceptor
下一篇
Day 24 - Spring Security (一) 基本概念與流程
系列文
誤打誤撞學了Spring Boot 還當了後端工程師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言