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

Print Friendly, PDF & Email

Leave a Reply

Your email address will not be published. Required fields are marked *