کانال بله, جهت پشتیبانی و اطلاع رسانی کانال بله, جهت پشتیبانی و اطلاع رسانی
عضویت

آموزش SP AspectJ Annotation-Java Spring

نماد گذاری(annotation) SP AspectJ

مثال نماد گذاری AOP AspectJ در اسپرینگ

فریمورک اسپرینگ در مقابل پیاده سازی AOP در اسپرینگ 1.2 سبک قدیمی مبتنی بر dtd (Spring 1.2 old style dtd based)، پیاده سازی AOP AspectJ اسپرینگ را به شما توصیه می کند، زیرا کنترل بیشتری در اختیار شما قرار می دهد و استفاده از آن آسان تر است. دو روش برای استفاده از پیاده سازی AOP AspectJ اسپرینگ وجود دارد:

  • با استفاده از نماد گذاری : که در اینجا آن را فرا خواهیم گرفت.
  • با استفاده از پیکر بندی xml (مبتنی بر schema) : که در بخش بعدی به آن می پردازیم.

پیاده سازی AOP AspectJ اسپرینگ نماد های بسیاری را ارائه می کند:

  • @Aspect کلاس را به عنوان جنبه اعلام می کند.
  • @Pointcut عبارت pointcut را اعلام می کند.

نمادهای استفاده شده برای ایجاد توصیه ها به شرح زیر است:

  • @Before ، before advice را اعلام می کند و پیش از فراخوانی متد اصلی(actual method) اعمال می شود.
  • @After ، after device را اعلام می کند و پس از فراخوانی متد اصلی و پیش از بازگرداندن نتایج اعمال می شود.
  • @AfterReturning ، after returning advice را اعلام می کند و پس از فراخوانی متد اصلی و پیش از بازگرداندن نتایج اعمال می شود اما می توان مقدار نتیجه را در توصیه گرفت.
  • @Around ، around advice را اعلام می کند و قبل و بعد از فراخوانی متد اصلی اعمال می شود.
  • @AfterThrowing ، throws advice را اعلام می کند و اگر متد اصلی استثنا پرتاب کند(خطا رخ دهد) اعمال می شود.

درک pointcut

Pointcut یک زبان اصطلاحی(expression language) در AOP اسپرینگ است. از نماد @Pointcut برای تعریف pointcut استفاده می شود. علاوه بر این نیز میتوان با نام، به عبارت pointcut ارجاع داد. مثالی ساده از عبارت pointcut را می بینیم.

@Pointcut("execution(* Operation.*(..))")  
private void doSomething() {}  

نام عبارت pointcut ، doSomething() است و صرف نظر از نوع بازگرداندن، روی تمام متدهای کلاس operation اعمال می شود.


درک عبارات pointcut (pointcut expressions)

بیایید بر اساس مثال زیر عبارات pointcut را یاد بگیریم.

@Pointcut("execution(public * *(..))")  

روی تمام متدهای عمومی(public method) اعمال خواهد شد.

@Pointcut("execution(public Operation.*(..))")    

روی تمام متدهای عمومی کلاس operation اعمال خواهد شد.

@Pointcut("execution(* Operation.*(..))")  

روی تمام متدهای کلاس operation اعمال خواهد شد.

@Pointcut("execution(public Employee.set*(..))")  

روی تمام متدهای setter عمومی کلاس employee اعمال خواهد شد.

@Pointcut("execution(int Operation.*(..))")  

روی تمام متدهای کلاس operation که مقدار از نوع int بر می گردانند، اعمال خواهد شد.


1- مثال @Before

AspectJ Before Advice قبل از متد actual business logic اعمال می شود. هر عملی از جمله تبدیل و احراز هویت را میتوان در اینجا اعمال کرد. کلاسی شامل actual business logic ایجاد کنید.

File: Operation.java

package com.javatpoint;  
public  class Operation{  
    public void msg(){System.out.println("msg method invoked");}  
    public int m(){System.out.println("m method invoked");return 2;}  
    public int k(){System.out.println("k method invoked");return 3;}  
}  

حال یک کلاس جنبه (aspect class) شامل before advice ایجاد کنید.

File: TrackOperation.java

package com.javatpoint;  
  
import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Before;  
import org.aspectj.lang.annotation.Pointcut;  
  
@Aspect  
public class TrackOperation{  
    @Pointcut("execution(* Operation.*(..))")  
    public void k(){}//pointcut name  
      
    @Before("k()")//applying pointcut on before advice  
    public void myadvice(JoinPoint jp)//it is advice (before advice)  
    {  
        System.out.println("additional concern");  
        //System.out.println("Method Signature: "  + jp.getSignature());  
    }  
}  

اکنون متد actual را فراخوانی می کنیم.

File: Test.java

package com.javatpoint;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Test{  
    public static void main(String[] args){  
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
        Operation e = (Operation) context.getBean("opBean");  
        System.out.println("calling msg...");  
        e.msg();  
        System.out.println("calling m...");  
        e.m();  
        System.out.println("calling k...");  
        e.k();  
    }  
}  

خروجی :

1. calling msg...

2. additional concern

3. msg() method invoked

4. calling m...

5. additional concern

6. m() method invoked

7. calling k...

8. additional concern

9. k() method invoked


همانطور که مشاهده می کنید، دغدغه اضافی قبل از فراخوانی متدهای msg() ، m() و k() چاپ شده است. حال اگر عبارت pointcut را مانند کد زیر تغییر دهید:

@Pointcut("execution(* Operation.m*(..))")   

دغدغه اضافی برای متدهایی از کلاس operation که با m شروع می شوند، اعمال خواهد شد. خروجی به صورت زیر است.

1. calling msg...

2. additional concern

3. msg() method invoked

4. calling m...

5. additional concern

6. m() method invoked

7. calling k...

8. k() method invoked


حال می بینید که دغدغه اضافی قبل از فراخوانی متد k() چاپ نمی شود.


2- مثال @after

AspectJ after advice پس از فراخوانی متدهای actual business logic اعمال می شود. از آن برای نگهداری وقایع، امنیت، اعلانات و غیره استفاده می شود. فرض بر این است که فایل های Operation.java، applicationContext.xm و Test.java مشابه فایل های مثال @before است. کلاس جنبه شامل after advice را ایجاد کنید.

File: TrackOperation.java

package com.javatpoint;  
  
import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.After;  
import org.aspectj.lang.annotation.Pointcut;  
  
@Aspect  
public class TrackOperation{  
    @Pointcut("execution(* Operation.*(..))")  
    public void k(){}//pointcut name  
      
    @After("k()")//applying pointcut on after advice  
    public void myadvice(JoinPoint jp)//it is advice (after advice)  
    {  
        System.out.println("additional concern");  
        //System.out.println("Method Signature: "  + jp.getSignature());  
    }  
}   

خروجی :

1. calling msg...

2. msg() method invoked

3. additional concern

4. calling m...

5. m() method invoked

6. additional concern

7. calling k...

8. k() method invoked

9. additional concern


می بینیم که دغدغه اضافی پس از فراخوانی متدهای msg() ، m() و k() چاپ شده اند.


3- مثال @afterReturning

با استفاده از after returning advice میتوان در توصیه نتایج را گرفت. یک کلاس شامل business logic ایجاد کنید.

File: Operation.java

package com.javatpoint;  
public  class Operation{  
    public int m(){System.out.println("m() method invoked");return 2;}  
    public int k(){System.out.println("k() method invoked");return 3;}  
}     

حال کلاس جنبه شامل after returning advice را ایجاد کنید.

File: TrackOperation.java

package com.javatpoint;  
  
import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.annotation.AfterReturning;  
import org.aspectj.lang.annotation.Aspect;  
  
@Aspect  
public class TrackOperation{  
    @AfterReturning(  
              pointcut = "execution(* Operation.*(..))",  
              returning= "result")  
                
    public void myadvice(JoinPoint jp,Object result)//it is advice (after returning advice)  
    {  
        System.out.println("additional concern");  
        System.out.println("Method Signature: "  + jp.getSignature());  
        System.out.println("Result in advice: "+result);  
        System.out.println("end of after returning advice...");  
    }  
}     

فایل File: applicationContext.xml مشابه مثال @before advice است. حال یک کلاس test که متدهای actual را فراخوانی می کند، ایجاد کنید.

package com.javatpoint;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Test{  
    public static void main(String[] args){  
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
        Operation e = (Operation) context.getBean("opBean");  
        System.out.println("calling m...");  
        System.out.println(e.m());  
        System.out.println("calling k...");  
        System.out.println(e.k());  
    }  
}    

خروجی :

1. calling m...

2. m() method invoked

3. additional concern

4. Method Signature: int com.javatpoint.Operation.m()

5. Result in advice: 2

6. end of after returning advice...

7. 2

8. calling k...

9. k() method invoked

10.additional concern

11.Method Signature: int com.javatpoint.Operation.k()

12.Result in advice: 3

13.end of after returning advice...

14.3


مشاهده می کنید که مقدار بازگردانده شده دو مرتبه چاپ شده است؛ یک بار توسط کلاس TrackOperation و بار دوم توسط کلاس test.


4- مثال @around

AspectJ around advice قبل و بعد از فراخوانی متدهای actual business logic اعمال می شود. فرض بر این است که فایل applicationContext.xml مشابه فایل داده شده در مثال @before است. کلاسی شامل actual business logic ایجاد کنید.

File: Operation.java

package com.javatpoint;  
public  class Operation{  
    public void msg(){System.out.println("msg() is invoked");}  
    public void display(){System.out.println("display() is invoked");}  
}     

کلاس جنبه شامل around advice را ایجاد کنید. به منظور پیشبرد درخواست توسط فراخوانی متد proceed()، باید مرجع PreceedingJoinPoint را در متد توصیه پاس دهید.

File: TrackOperation.java

package com.javatpoint;  
import org.aspectj.lang.ProceedingJoinPoint;  
import org.aspectj.lang.annotation.Around;  
import org.aspectj.lang.annotation.Aspect;  
import org.aspectj.lang.annotation.Pointcut;  
  
@Aspect  
public class TrackOperation  
{  
    @Pointcut("execution(* Operation.*(..))")  
    public void abcPointcut(){}  
      
    @Around("abcPointcut()")  
    public Object myadvice(ProceedingJoinPoint pjp) throws Throwable   
    {  
        System.out.println("Additional Concern Before calling actual method");  
        Object obj=pjp.proceed();  
        System.out.println("Additional Concern After calling actual method");  
        return obj;  
    }  
}      

حال یک کلاس test که متدهای actual را فراخوانی می کند ایجاد کنید.

package com.javatpoint;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Test{  
    public static void main(String[] args){  
        ApplicationContext context = new classPathXmlApplicationContext("applicationContext.xml");  
          
        Operation op = (Operation) context.getBean("opBean");  
        op.msg();  
        op.display();  
    }  
}      

خروجی :

1. Additional Concern Before calling actual method

2. msg() is invoked

3. Additional Concern After calling actual method

4. Additional Concern Before calling actual method

5. display() is invoked

6. Additional Concern After calling actual method


می بینیم که دغدغه اضافی قبل و بعد از فراخوانی متدهای msg() وdisplay چاپ شده اند.


5- مثال @afterThrowing

با استفاده از after throwing advice می توان استثنا را در کلاس TrackOperation چاپ کرد. مثالی از AspectJ AfterThrowing advice را در ادامه می بینیم. کلاسی شامل business logic ایجاد کنید.

File: Operation.java

package com.javatpoint;  
public  class Operation{  
    public void validate(int age)throws Exception{  
    if(age<18){ throw new ArithmeticException("Not valid age");
                }
                else{
                System.out.println("Thanks for vote");
                }
                }
                }

یک کلاس جنبه شامل after throwing advice ایجاد کنید. همچنین در اینجا نیاز داریم تا مراجع قابل پرتاب را پاس دهیم، تا در نتیجه بتوانیم استثنا را رهگیری کنیم.

File: TrackOperation.java

package com.javatpoint;  
import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.annotation.AfterThrowing;  
import org.aspectj.lang.annotation.Aspect;  
@Aspect  
public class TrackOperation{  
    @AfterThrowing(  
              pointcut = "execution(* Operation.*(..))",  
              throwing= "error")  
                
    public void myadvice(JoinPoint jp,Throwable error)//it is advice  
    {  
        System.out.println("additional concern");  
        System.out.println("Method Signature: "  + jp.getSignature());  
        System.out.println("Exception is: "+error);  
        System.out.println("end of after throwing advice...");  
    }  
}        

فایل File: applicationContext.xml مشابه مثال @before است. حال یک کلاس test که متدهای actual را فراخوانی می کند ایجاد کنید.

package com.javatpoint;  
  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
public class Test{  
    public static void main(String[] args){  
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");  
        Operation op = (Operation) context.getBean("opBean");  
        System.out.println("calling validate...");  
        try{  
            op.validate(19);  
        }catch(Exception e){System.out.println(e);}  
        System.out.println("calling validate again...");  
          
        try{  
            op.validate(11);  
        }catch(Exception e){System.out.println(e);}  
    }  
}     

خروجی :

1. calling validate...

2. Thanks for vote

3. calling validate again...

4. additional concern

5. Method Signature: void com.javatpoint.Operation.validate(int)

6. Exception is: java.lang.ArithmeticException: Not valid age

7. end of after throwing advice...

8. java.lang.ArithmeticException: Not valid age


1398/12/19 2687 515
رمز عبور : tahlildadeh.com یا www.tahlildadeh.com
نظرات شما

نظرات خود را ثبت کنید...