Spring – 32 – Aspect Oriented Programming (AOP) – 06 – AspectJ with Annotation
Merhaba Arkadaslar
Bu bolumde AOP yaklasimini AspectJ Annotation ile inceleyelim.
AspectJ XML yaklasiminda kullandigimiz kodlari , Annotation yaklasimi ile kullanacagiz.
Spring – 30 – Aspect Oriented Programming (AOP) – 04 – AspectJ with XML
Bu bolumde kullanacagimiz Annotation’lar;
- @Aspect
- @EnableAspectJAutoProxy
- @Before
- @After
- @AfterReturning
- @AfterThrowing
- @Around
Service
EmployeeService.java
EmployeeService sinifimizi AspectJ XML ornegimizde kullanmistik. Burada basit CRUD metotlarinin simulasyonunu yapiyoruz. Her bir metotla bir Aspect Type’i iliskilendirecegiz.
Ornegin ; comment line’dan anlasilacagi gibi saveEmployee metodunu calismadan once logBefore metodu calisacaktir.
package _37.aspectj.annotation.service; import java.util.List; public class EmployeeService { public void saveEmployee() { // AuditServiceAspect#logBefore will be invoked "before" System.out.println("saveEmployee is invoked..."); } public void updateEmployee() { // AuditServiceAspect#logafter will be invoked "after" System.out.println("updateEmployee is invoked..."); } public String getEmployeeId() { // AuditServiceAspect#logAfterReturning will be invoked "after-returning" System.out.println("getEmployeeId is invoked..."); return "Emp-1000"; } public void deleteEmployee() { // AuditServiceAspect#logAfterThrowing will be invoked "after-throwing" System.out.println("deleteEmployee is invoked..."); throw new RuntimeException(); } public List<Object> getAllEmployees() { // AuditServiceAspect#logAround will be invoked "around" System.out.println("getAllEmployees is invoked..."); // return null; } }
@Aspect & @Before
AuditServiceAspect.java
EmployeeService#saveEmployee metodunda yorum satirinda logBefore yer aliyordu.
@Before annotation kullanalim ve execution olarak ilgili saveEmployee metodunu belirtelim. Boylece EmployeeService#saveEmployee metodu calismadan once logBefore metodu calisacaktir.
package _37.aspectj.annotation.service; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect @EnableAspectJAutoProxy public class AuditServiceAspect { @Before("execution(* _37.aspectj.annotation.service.EmployeeService.saveEmployee(..))") public void logBefore() { System.out.println("logBefore is invoked..."); } }
AuditServiceAspect sinifimizda @Aspect ve @Before annotation’larini kullandik. XML yaklasiminda karsiligi ;
<aop:config> <aop:aspect id="myaspect" ref="auditServiceAspectId"> <!-- Before --> <!--It is valid too! --> <!-- <aop:pointcut id="pointCutBeforeId" expression="execution(* execution(* _37.aspectj.annotation.service.EmployeeService.saveEmployee(..))" /> --> <aop:pointcut id="pointCutBeforeId" expression="execution(* *.saveEmployee(..))" /> <aop:before method="logBefore" pointcut-ref="pointCutBeforeId" /> </aop:aspect> </aop:config>
Bir diger nokta olarak dikkat edecek olursak @EnableAspectJAutoProxy annotation’ini kullandik. Boylece AspectJ Annotation’larini kullanabiliriz.@EnableAspectJAutoProxy annotation’ini kullanabilmek icin <context:annotation-config> tag’ini da kullanmamiz gereklidir. Tabi bu noktada context xmlns ‘de eklemek gereklidir.Bir diger konfigurasyon olarak <aop:aspectj-autoproxy/> tag’ini kullanabiliriz. Bu noktada aop xmlns aktif olmalidir.37.aspectj.annotation.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd "> <!-- do not forget adding xmlns context! --> <context:annotation-config/> <!-- Use @EnableAspectJAutoProxy with context:annotation-config or <aop:aspectj-autoproxy/> --> <bean id="employeeService" class="_37.aspectj.annotation.service.EmployeeService" /> <bean id="auditServiceAspect" class="_37.aspectj.annotation.service.AuditServiceAspect" /> </beans>
AspectJAnnotationTest.java
package _37.aspectj.annotation.test; import org.springframework.context.support.ClassPathXmlApplicationContext; import _37.aspectj.annotation.service.EmployeeService; public class AspectJAnnotationTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("37.aspectj.annotation.xml"); EmployeeService employeeService = context.getBean(EmployeeService.class); //@Before employeeService.saveEmployee(); context.close(); } }
Ornegimizi calistirdigimizda ;saveEmployee metodundan once @Before annotation’ini kullandigimiz logBefore metodu calisacaktir.
logBefore is invoked... saveEmployee is invoked...
@After
@After annotation da <aop:after> tag’ina karsilik gelecektir. Benzer tanimlamayi logAfter metodunda yapalim. execution olarak EmployeeService#updateEmployee metodunu veriyoruz. Boylece updateEmployee metodundan sonra logAfter metodu calisacaktir.AuditServiceAspect.java
package _37.aspectj.annotation.service; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.context.annotation.EnableAspectJAutoProxy; @Aspect @EnableAspectJAutoProxy public class AuditServiceAspect { //...... @After("execution(* _37.aspectj.annotation.service.EmployeeService.updateEmployee(..))") public void logAfter() { System.out.println("logAfter is invoked..."); } }
XML konfigurasyonunda su sekilde tanim yapmistik ;
<!-- After --> <aop:pointcut id="pointCutAfterId" expression="execution(* *.updateEmployee(..))" /> <aop:after method="logAfter" pointcut-ref="pointCutAfterId" />
AspectJAnnotationTest.java
//... public class AspectJAnnotationTest { public static void main(String[] args) { ///,.... //@After System.out.println(); employeeService.updateEmployee(); context.close(); } }
Ornegimizi calistirdigimida ; updateEmployee metodundan sonra @After annotation’ini kullandigimiz logAfter metodu calisacaktir.
updateEmployee is invoked... logAfter is invoked...
@AfterReturning
@AfterReturning annotation’ini <after-returning> tag’ina karsilik gelecektir. Burada dikkat edecek olursak pointcut ve returning attribute’lerini kullaniyoruz. Burada String resultValue ile returning=”resultValue” ayni isimde olduguna dikkat edelim.
AuditServiceAspect.java
@AfterReturning(pointcut = "execution(* _37.aspectj.annotation.service.EmployeeService.getEmployeeId(..))", returning = "resultValue") public void logAfterReturning(JoinPoint joinPoint, String resultValue) { System.out.println("logAfterReturning is invoked..."); System.out.println("Invoked by : " + joinPoint.getSignature().getName()); System.out.println("Returned value : " + resultValue); }
XML konfigurasyonunda su sekilde tanim yapmistik ;
<!-- AfterReturning --> <aop:pointcut id="pointCutAfterReturningId" expression="execution(* *.getEmployeeId(..))" /> <aop:after-returning method="logAfterReturning" returning="resultValue" pointcut-ref="pointCutAfterReturningId" />
AspectJAnnotationTest.java
//@AfterReturning System.out.println(); employeeService.getEmployeeId();
Ornegimizi calistirdigimizda , getEmployeeId metodu calistiginda donen degerin resultValue parametresine bind edildigine/baglandigina dikkat edelim.JoinPoint parametresi ile hangi metottan cagrilmis/invoke/call gibi bilgilere ulasabiliriz.
getEmployeeId is invoked... logAfterReturning is invoked... Invoked by : getEmployeeId Returned value : Emp-1000
@AfterThrowing
@AfterThrowing annotation’i <aop:after-throwing> tag’ina karsilik gelmektedir.
AuditServiceAspect.java
@AfterThrowing(pointcut="execution(* _37.aspectj.annotation.service.EmployeeService.deleteEmployee(..))" ,throwing="thrownException") public void logAfterThrowing(JoinPoint joinPoint, Exception thrownException) { System.out.println("logAfterThrowing is invoked..."); System.out.println("Called by : " + joinPoint.getSignature().getName()); System.out.println("Exception : " + thrownException); }
XML konfigurasyonunda su sekilde tanim yapmistik ;
<!-- AfterThrowing --> <aop:pointcut id="pointCutAfterThrowingId" expression="execution(* *.deleteEmployee(..))" /> <aop:after-throwing method="logAfterThrowing" throwing="thrownException" pointcut-ref="pointCutAfterThrowingId" />
throwing attribute’e dikkat edelim ! Exception thrownException parametresi ile throwing attribute’teki isim ayni.
AspectJAnnotationTest.java
System.out.println(); // @AfterThrowing try { employeeService.deleteEmployee(); } catch (Exception e) { // TODO: handle exception }
Ornegi calistirdigimizda deleteEmployee metodu calisacaktir , bu metotda Exception firlatiyoruz , logAfterThrowing metodu calisacaktir.
deleteEmployee is invoked... logAfterThrowing is invoked... Invoked by : deleteEmployee Exception : java.lang.RuntimeException
@AfterAround
@AfterAround annotation’ini <aop:around> tag’ina karsilik gelecektir.
AuditServiceAspect.java
@Around("execution(* _37.aspectj.annotation.service.EmployeeService.getAllEmployees(..))") public void logAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("logAround is invoked..."); System.out.println("Invoked by : " + joinPoint.getSignature().getName()); System.out.println("Around before is running!"); joinPoint.proceed(); System.out.println("Around after is running!"); }
XML konfigurasyonunda su sekilde tanim yapmistik ;
<!-- Around --> <aop:pointcut id="pointCutAround" expression="execution(* *.getAllEmployees(..))" /> <aop:around method="logAround" pointcut-ref="pointCutAround" />
AspectJAnnotationTest.java
System.out.println(); // @AfterAround employeeService.getAllEmployees();
Ornegimizi calistirdigimizda logAround metodu ilk olarak calismaktadir , sonrasinda JoinPoint#proceed metodunu cagiriyoruz , bu noktada getAllEmployees metodu calismaktadir. Sonrasinda tekrar logAround metoduna donus olmaktadir ve logAround metodu tamamlanmaktadir.
logAround is invoked... Invoked by : getAllEmployees Around before is running! getAllEmployees is invoked... Around after is running!
Github kaynak dosyalar/ source folderleventerguder/injavawetrust-spring-tutorial
Yazimi burada sonlandiriyorum.Herkese bol Javali gunler dilerim.Be an oracle man , import java.*;Levent ErguderOCP, Java SE 6 ProgrammerOCE, Java EE 6 Web Component Developer
Leave a Reply