【java】java中的AOP思想(一)

本人菜雞一個,寫這個系列的文章是爲了通過把自己理解AOP的心路歷程記錄下來,加深自己對這個思想的印象~

背景:

其實一開始聽到AOP這個概念的時候,是自己剛學java沒多久的時候,那時候很懵逼啊,這都什麼鬼啊?

所以寫這篇文章的時候,希望能夠把自己理解的線路描繪出來。

一、我們從代碼簡潔和優化的初衷!

來往後看,理解什麼是AOP思想!

舉個例子,當我們一個java代碼被調用的時候,我想記錄一些指標(其實不就是打印日誌需求)

public void functionA(){
    System.out.println("functionA調用開始")
    //方法邏輯....

    System.out.println("functionA調用結束")
}

很簡單,這樣就可以完成我們的需求。

 

二、然後我們開始想,如何優化這個功能?

1、不使用System.out.print來打印,想用一些封裝的打印類

當然我們可以自己實現一個打印類,或者使用現有的,比如log4j

private static final Logger logger = LoggerFactory.getLogger(當前類.class);
public void functionA(){
    logger.info("functionA調用開始")
    //方法邏輯....

    logger.info("functionA調用結束")
}

2、甚至我們覺得直接這樣調用不好(想讓打印出來的日誌格式統一),因此我們寫了方法來封裝他

private static final Logger logger = LoggerFactory.getLogger(當前類.class);

public void printLog(String type,String funcName){
    if(type=="start"){
        logger.info(funcName+"調用開始")
    }else{
         logger.info(funcName+"調用結束")
    }

}

public void functionA(){
    printLog("start","functionA")
    //方法邏輯....
    printLog("end","functionA")
   
}

public void functionB(){
    printLog("start","functionB")
    //方法邏輯....
    printLog("end","functionB")
   
}

 到此爲止,你已經做出了兩步優化,這是在代碼改動最少的情況下,能做出的最大的優化!

 

三、有沒有更好的優化方法?

我想要實現那種,只需要寫代碼邏輯,然後日誌這些亂七八糟的東西,我不需要用代碼來指定打印,自動打印就好了。

如果你有這種想法的話,恭喜,AOP就是因爲這種想法誕生的!

這裏暫且不討論在spring中如何使用aop的註解來實現日誌的打印

我們來想想,就上面的那部分代碼如何優化?

-1、做一個抽象類,實現了打印日誌的具體方法,並且留下一個run方法給實現類實現

public abstract class CommonJob {
	public Logger logger ;

	protected CommonJob( Logger logger) {
		this.logger = logger;
	}
   
	public void beforeLog(){
    	logger.info("調用開始")
	}
	public void afterLog(){
    	logger.info("調用結束")
	}
    public void error(){
    	logger.error("調用失敗")
	}

	public abstract void run();

}

-2、必須有個地方調用打印日誌和run方法

public class CommonAnalyzer {

	public void runJob(CommonJob job){
        try{
            
            job.beforeLog();
            job.run();
            job.afterLog();
			
        } catch (Exception e) {
            job.error(e); 
        }
    }

}

-3、然後調用

public class AModelAnalyzer extends CommonAnalyzer {
    private static final Logger logger = LoggerFactory.getLogger(當前類.class);
    public void functionA(){
        runJob(new CommonJob(logger){
            @Override
            public void run() {
            //具體代碼邏輯
			//balabalabala....
		    }
		});
	}

    public void functionB(){
        runJob(new CommonJob(logger){
            @Override
            public void run() {
			//具體代碼邏輯
			//balabalabala....
			}	
		});
	}


    public static void main(String[] args){
		functionB();
		functionA();
    }
}

 

這樣,我們就只需要在調用runJob方法的時候傳入CommonJob類的實現類,或者在runJob中實現一個匿名內部類!

-4、甚至當處理邏輯一樣的時候,我們可以寫一個CommonJob的實現類,這樣就可以複用相同的run代碼,

好比這樣!

public class SelfCommonJob extends CommonJob {
    //當有一些處理邏輯一樣的不同模塊的job,
    //可以寫一些參數,在run執行的時候做判斷
    
    public SelfCommonJob(Logger logger){
    }    

    //實現run
    public void run(){
    //代碼邏輯...
    }
   
}
public class AModelAnalyzer extends CommonAnalyzer {
    private static final Logger logger = LoggerFactory.getLogger(當前類.class);
    private SelfCommonJob scj = new SelfCommonJob (logger);
    public void functionA(){
        runJob(scj);
	}

    public void functionB(){
        runJob(scj);
	}


    public static void main(String[] args){
		functionB();
		functionA();
    }
}

 當然這只是很基礎的模型,但是這就是AOP的思想,程序員調用這個方法的時候,只需要關注run方法裏面的代碼邏輯就可以了,不需要關注其他打印日誌,判斷執行時間等等一系列的事情!我覺得還是蠻方便的~

好了,這篇文章就到這裏,其實如果是一位java程序員應該對spring中AOP的使用蠻熟悉的,下一篇我會分享下在spring中如何實現這樣的功能,下次再見~

本人菜雞一隻,如果有哪裏寫得不對,或者誤導了大家的,請批評指出,本人一定虛心接受,堅決改正!

 也提醒下自己:“驕傲在敗壞以先,狂心在跌倒之前!”

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章