AspectJ簡(jiǎn)介
AOP雖然是方法論播瞳,但就好像OOP中的Java一樣,一些先行者也開發(fā)了一套語言來支持AOP。目前用得比較火的就是AspectJ了塔沃,它是一種幾乎和Java完全一樣的語言腰奋,而且完全兼容Java(AspectJ應(yīng)該就是一種擴(kuò)展Java单起,但它不是像Groovy那樣的拓展)。當(dāng)然氛堕,除了使用AspectJ特殊的語言外馏臭,AspectJ還支持原生的Java,只要加上對(duì)應(yīng)的AspectJ注解就好讼稚。所以括儒,使用AspectJ有兩種方法:
1.完全使用AspectJ的語言。這語言一點(diǎn)也不難锐想,和Java幾乎一樣帮寻,也能在AspectJ中調(diào)用Java的任何類庫(kù)。AspectJ只是多了一些關(guān)鍵詞罷了赠摇。
2.或者使用純Java語言開發(fā)固逗,然后使用AspectJ注解,簡(jiǎn)稱@AspectJ藕帜。
AspectJ現(xiàn)在托管于Eclipse項(xiàng)目中烫罩,官方網(wǎng)站是:
詳情請(qǐng)查看: 深入理解Android之AOP
下面我們以簡(jiǎn)單的程序來看下最簡(jiǎn)單的AspectJ語法:
@Aspect
public class AspectJTest {
private static final String TAG ="AspectJTest" ;
@Before("execution (* android.app.Activity.on**(..))")
public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable{
Log.e(TAG,joinPoint.getSignature().toString()+":beforecall"); }
}
- @Aspect: 注解表明這是一個(gè)AspectJ文件贝攒,編譯器在編譯的時(shí)候,就會(huì)自動(dòng)去解析时甚,然后將代碼注入到相應(yīng)的JPonit中隘弊。
- @Before: Advice,也就是具體的插入點(diǎn)哈踱。
- execution: 處理JPoint的類型,例如call梨熙,execution
-
(* android.app.Activity.on**(..)):這個(gè)是最重要的表達(dá)式开镣,第一個(gè)[]表示返回值,* 表示返回任意類型咽扇,后面的android.app.Activity.on**表示典型的包名路徑邪财,其中可用 * 來進(jìn)行通配,幾個(gè) * 都沒有區(qū)別肌割。同時(shí)卧蜓,這里可以通過 &&,||,! 來進(jìn)行條件組合,例如:
@Before("execution ( android.app.Activity.onCreate(..)) || "
+ "execution (* android.app.Activity.onDestroy())")
public void onActivityMethodBefore(JoinPoint joinPoint) throws Throwable{
Log.e(TAG,joinPoint.getSignature().toString()+":beforecall");
}
從上面的例子我們可以看出把敞,前面所用的AOP代碼注入方法都是直接指定相應(yīng)的pointcut進(jìn)行切入弥奸。如果說此時(shí)我們又需要對(duì)某個(gè)函數(shù)進(jìn)行代碼切入,那么我們又必須重新寫一個(gè)相應(yīng)的pointcut奋早,重新寫個(gè)方法進(jìn)行代碼切入盛霎。那么,有沒有更加方便的一種方法耽装,可以讓我們很方便的直接進(jìn)行指定就能實(shí)現(xiàn)代碼切入呢愤炸?通過自定義Pointcuts的方法可以實(shí)現(xiàn)上述所需功能。
自定義Pointcuts
自定義Pointcuts可以讓我們更加精確的切入一個(gè)或多個(gè)指定的切入點(diǎn)掉奄。其具體操作步驟如下:
1.首先规个,我們需要自定義一個(gè)注解類
@Retention(RetentionPolicy.CLASS)
@Target({ElementType.CONSTRUCTOR,ElementType.METHOD})
public @interface AopLog {}
2.然后,創(chuàng)建一個(gè)切面文件姓建,內(nèi)部通過一個(gè)Pointcut來指定在帶有我們上面自定義注解類AopLog注解的所有方法上進(jìn)行攔截诞仓。
@Aspect
public class AopLogPointcut {
//在帶有AopLog注解的方法進(jìn)行切入(注:此處的 * *前面都要有一個(gè)空格)
@Pointcut("execution(@com.yn.aspectj.selfmakeaop.AopLog * *(..))")
public void logPointcut(){} //注意,這個(gè)函數(shù)必須要有實(shí)現(xiàn)速兔,否則Java編譯器會(huì)報(bào)錯(cuò)
@After("logPointcut()")
public void onLogPointcutAfter(JoinPoint joinPoint) throws Throwable{
Log.i("AOP","onLogPointcutAfter:"+joinPoint.getSignature());
}
}
3.最后墅拭,只需要在要進(jìn)行切入的函數(shù)前加上@AopLog注解即可。
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
testAopLog();
}
@AopLog
public void testAopLog() {
Log.i("AOP","in testAopLog");
}
}
掌握上述方法涣狗,則AOP基本編程便可以使用了谍婉。