AspectJ


 spectJ是Java的一個AOP框架,可以單獨使用,也可以整合到其它框架中。

 

單獨使用AspectJ時需要使用專門的編譯器ajc。

java的編譯器是javac,AspectJ的編譯器是ajc,aj是首字母縮寫,c即compiler。

 

此處介紹如何單獨使用AspectJ。

 

 


 

  

下載AspectJ所需的jar包

https://www.eclipse.org/aspectj/downloads.php

 

下載得到的是一個jar包,不能直接使用,解壓,得到3個jar包:

 

單獨使用AspectJ時,只需添加aspectjrt.jar。

 

 


 

 

IDEA環境配置

1、安裝插件

 

 

2、使用專門的編譯器

 

 


 

 

Demo

(1)新建Java項目,添加aspectjrt.jar。只添加這一個jar包就ok。

 

(2)新建包com.chy.dao,包下新建接口UserDao、實現類UserDaoImpl:

public interface UserDao {
    public void addUser(int i,String str);
    public void deleteUser();
}
public class UserDaoImpl implements UserDao {
    @Override
    public void addUser(int i,String str) {
        System.out.println("正在添加用戶...");
    }

    @Override
    public void deleteUser() {
        System.out.println("正在刪除用戶...");
    }
}

 

 

(3)新建包com.chy.aspect,包下新建類UserDaoAspect:

//需要用@Aspect標注
@org.aspectj.lang.annotation.Aspect
public class UserDaoAspect {
    /*
    配置全局切入點
    返回值類型  類|接口名.方法名(參數表)
    參數表可使用具體類型,比如(int,String),也可用(..)表示任意類型、個數的參數
     */
    @Pointcut("execution(* com.chy.dao.UserDao.*(..))")
    private void pointCut(){}

    /*
    前置通知
    可以引用全局切入點,也可以現配:
    @Before("execution(void com.chy.dao.UserDao.*(..))")
     */
    @Before("pointCut()")
    public void before(){
        System.out.println("正在執行前置通知...");
    }

    //后置通知
    @After("pointCut()")
    public void after(){
        System.out.println("正在執行后置通知...");
    }

    //返回通知
    @AfterReturning("pointCut()")
    public void afterReturning(){
        System.out.println("正在執行返回通知...");
    }

    //異常通知
    @AfterThrowing("pointCut()")
    public void  afterThrowing(JoinPoint point){
        System.out.println("正在執行異常通知...");

        //獲取目標對象,返回值是Object類型
        Object target = point.getTarget();

        //目標方法名,String
        System.out.println("目標方法:"+point.getSignature());

        //需要轉換一下才能得到具體的實參
        List<Object> args = Arrays.asList(point.getArgs());
        System.out.println("實參表:"+args);
    }

}

方法名任意,因為要用注解標注此方法是用來實現哪種通知的。

可傳入一個JointPoint類型的參數,表示連接點。

 

 

環繞通知:

    /*
    環繞通知
    需要傳入一個ProceedingJoinPoint類型的參數,用於調用目標方法。
    如果要代理多個方法,返回值最好聲明為Object,因為多個方法的返回值類型可能不相同
    */
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        //前增強
        System.out.println("正在執行前增強...");
        //調用目標方法
        Object obj = point.proceed();
        //后增強
        System.out.println("正在執行后增強...");
        //返回目標方法的返回值
        return obj;
    }

環繞通知與其它通知有重疊,不能一起使用。

 

 

(4)使用

UserDao user=new UserDaoImpl();
user.addUser();

AspectJ增強的是方法,調用方法時,會自動調用對應的通知來增強。

 

 


 

 

切面的另一種寫法(了解)

包下新建Aspect:

 

//注意是aspect,不是class
public aspect UserDaoAspect {
    //配置全局切入點
    @Pointcut("execution(* com.chy.dao.UserDao.*(..))")
    private void pointCut(){}

    /*
    前置通知
    可以使用引用切入點,也可以現配:
    before():execution(void com.chy.dao.UserDao.*(..)){     }
     */ before():pointCut(){
        System.out.println("正在執行前置通知...");
    }

    //后置通知
 after():pointCut(){
        System.out.println("正在執行后置通知...");
    }
}

方法名是固定的:before、after,都是關鍵字,before表示前置通知,after表示后置通知。

 

此種方式很不好用,不推薦。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM