مشخصات مقاله
-
515
-
0.0
-
2687
-
0
-
0
آموزش 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