前言
剛加入新公司,一來項目組長就讓我帶3個實習生,也是鴨梨山大啊。今天在旁邊看他們寫代碼,感覺基礎的能力還是可以的,不過技術上面還是有不少欠缺的啊。
比如:項目組長讓他們把Service層,每個方法都要加上日誌打印,執行該方法之前的,執行之後的,還要打印方法參數值。看他們一直就那樣手動的log.debug()
,我也是很無奈。。當時就說了用AOP去實現很簡單的,尤其是本來項目就是基於SpringBoot的,連配置都省了。結果都不會,因爲我電腦還沒審批下來,當時就沒給他們演示了。回來寫了Demo,等電腦下來,就讓他們學學看,苦逼的花大半天加log,在我這裏只需要分分鐘的事,嘿嘿。
環境
- jdk1.8
- springboot 1.5.1.RELEASE
配置
需要注意的是,Maven的pom.xml
文件再原有的springboot配置之上還要加一個aop的,如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
添加以上配置會自動導入spring-aop, aspectjrt, aspectjweaver這幾個jar包的
AOP
這裏只爲了簡單的演示一下如何完成打印日誌需求:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
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.context.annotation.Configuration;
@Aspect
@Configuration
public class LoggerAopConfig {
private static final Logger log = LoggerFactory.getLogger(LoggerAopConfig.class);
// 只關注方法名爲find前綴的
@Pointcut("execution(* find* (..))")
public void executeService() {}
@Before("execution(* find*(..))")
public void invokeBefore(JoinPoint point) {
String realClassName = getRealClassName(point);
log.debug("調用-----"+ realClassName + " 執行 " + getMethodName(point) + " 方法之前");
}
@After("execution(* find*(..))")
public void invokeAfter(JoinPoint point) {
String realClassName = getRealClassName(point);
log.debug("調用-----"+ realClassName + " 執行 " + getMethodName(point) + " 方法之後");
}
/**
* 獲取被代理對象的真實類全名
* @param point 連接點對象
* @return 類全名
*/
private String getRealClassName(JoinPoint point) {
return point.getTarget().getClass().getName();
}
/**
* 獲取代理執行的方法名
* @param point 連接點對象
* @return 調用方法名
*/
private String getMethodName(JoinPoint point) {
return point.getSignature().getName();
}
}
其中關於JoinPoint有以下幾個常用方法:
- Object[] getArgs:返回目標方法的參數
- Signature getSignature:返回目標方法的簽名
- Object getTarget:返回被織入增強處理的目標對象
Object getThis:返回AOP框架爲目標對象生成的代理對象
注意:當使用@Around處理時,我們需要將第一個參數定義爲ProceedingJoinPoint類型,該類是JoinPoint的子類。
總結
技術是需要靈活變通的,當一個類似的代碼重複3-5遍的時候就應該要想想,有什麼辦法可以減少重複代碼了。當基礎技術學的差不多的時候,編程思想就能看出技術水平的高低啦,要想着擺脫低級搬磚碼農的處境,思想很關鍵。還要學的有很多,堅持。