Spring – 30 – Aspect Oriented Programming (AOP) – 04 – AspectJ with XML

Merhaba Arkadaslar
Bu bolumde AspectJ ile Spring AOP entegrasyonunu gerceklestirecegiz.
Sayfada documentation kullanilarak ogrenilebilir.

Inceleyecegiz AOP tag type’lari ;

  • <aop:before>
  • <aop:after>
  • <aop:after-returning>
  • <aop:after-throwing>
  • <aop:around>

Oncelikle AspectJ icin gerekli Maven dependency tanimlarini projemize ekleyelim.

Add Dependency

pom.xml

<properties>
	...
	<aspectj.version>1.8.9</aspectj.version>
	...
</properties>


<dependencies>
	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjrt</artifactId>
		<version>${aspectj.version}</version>
	</dependency>

	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjweaver</artifactId>
		<version>${aspectj.version}</version>
	</dependency>

</dependencies>

<aop:before>

Oncelikle basit bir Aspect sinifi olusturalim. Audit icin log’lama yapalim…

AuditServiceAspect.java

package _35.aspectj.service;

public class AuditServiceAspect {

	public void logBefore() {		
		System.out.println("logBefore is invoked...");
	}

}

EmployeeService sinifimizda saveEmployee metodumuz olsun. Bu metot oncesinde AuditServiceAspect#logBefore metodunu <aop:before> tagi yardimiyla cagiracagiz.

EmployeeService.java

package _35.aspectj.service;

public class EmployeeService {

	public void saveEmployee() {
		//AuditServiceAspect#logBefore will be called "before"
		System.out.println("saveEmployee is invoked...");
	}
}

35.aspectj.xml
Oncelikle XML konfigurasyon dosyamiza ilgili xlms ve xsi:schemaLocation ekleyelim ;

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
http://www.springframework.org/schema/aop 
http://www.springframework.org/schema/aop/spring-aop.xsd

Sonrasinda EmployeeService ve AuditServiceAspect icin bean tanimlarini gerceklestiriyoruz.
<aop:config> tag’i icerisinde <aop:aspect> tag’larini kullanabiliriz. <aop:aspect> taginda ref attribute’unde AuditServiceAspect bean’i kullaniyoruz.

<aop:pointcut> tag’ini kullanarak PointCut noktasi belirtiyoruz ; EmployeeService#saveEmployee

Son olarak AOP Type olarak <aop:before> tag’ini kullaniyoruz. pointcut-ref olarak <aop:pointcut> tag’i id bilgisini veriyoruz.

expression attribute’te execution(…) yardimiyla ilgili metodu cagirabiliriz.

method attribute olarak AuditServiceAspect#logBefore methodunu veriyoruz.

<?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"
	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 ">


	<bean id="employeeService" class="_35.aspectj.service.EmployeeService" />
	<bean id="auditServiceAspectId" class="_35.aspectj.service.AuditServiceAspect" />

	<aop:config>
		<aop:aspect id="myaspect" ref="auditServiceAspectId">

			<!-- Before -->
			<!--It is valid too! --> 
			<!-- 
			<aop:pointcut id="pointCutBeforeId" expression="execution(* _35.aspectj.service.EmployeeService.saveEmployee(..))" />
			-->
			
			<aop:pointcut id="pointCutBeforeId" expression="execution(* *.saveEmployee(..))" />
			<aop:before method="logBefore" pointcut-ref="pointCutBeforeId" />
			
		</aop:aspect>
	</aop:config>

</beans>

AspectJTest.java

package _35.aspectj.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import _35.aspectj.service.EmployeeService;

public class AspectJTest {

	public static void main(String[] args) {

		ApplicationContext ctx = new ClassPathXmlApplicationContext("35.aspectj.xml");

		EmployeeService employeeService = ctx.getBean("employeeService", EmployeeService.class);

		// aop:before
		employeeService.saveEmployee();

		((ClassPathXmlApplicationContext) ctx).close();
	}
}

Ornegimizi calistirdigimizda;
saveEmployee metodundan once logBefore metodu cagrilacaktir/invoke.

logBefore is invoked...
saveEmployee is invoked...

<aop:after>

<aop:after> yaklasiminda , ilgili metottan sonra calisacaktir.

AuditServiceAspect.java

package _35.aspectj.service;

public class AuditServiceAspect {

	public void logBefore() {		
		System.out.println("logBefore is invoked...");
	}

	public void logAfter() {
		System.out.println("logAfter is invoked...");
	}
	
}

EmployeeService.java

package _35.aspectj.service;

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...");
	}
}

Simdi de <aop:after> tag’ini kullanalim.
Yeni bir <aop:pointcut> tanimlayalim. <aop:after> tag’inda AuditServiceAspect#logAfter metodunu kullaniyoruz.

<aop:config>
	<aop:aspect id="myaspect" ref="auditServiceAspectId">

		....
		
		<!-- After -->
		<aop:pointcut id="pointCutAfterId" expression="execution(* *.updateEmployee(..))" />
		<aop:after method="logAfter" pointcut-ref="pointCutAfterId" />
		
	</aop:aspect>
</aop:config>

AspectJTest.java

	public static void main(String[] args) {
...
		System.out.println();

		// aop:after
		employeeService.updateEmployee();
....
       }

Ornegimizi calistirdigimizda;
updateEmployee metodu calistiktan sonra logAfter metodunun calistigini gorebiliriz.

logBefore is invoked...
saveEmployee is invoked...

updateEmployee is invoked...
logAfter is invoked...

<aop:after-returning>

<aop:after-returning> yaklasimini kullanarak metottan donen degere ulasabiliriz.
JoinPoint sinifi yardimiyla hangi metottan cagrildigi , gonderilen argumanlar gibi bilgilere erisim saglanabilmektedir.

AuditServiceAspect.java
logAfterReturning metodumuzda , JoinPoint ve String tipinde 2 parametre yer almaktadir.

package _35.aspectj.service;

import org.aspectj.lang.JoinPoint;

public class AuditServiceAspect {

	....
	....
	public void logAfterReturning(JoinPoint joinPoint, String resultValue) {
		System.out.println("logAfterReturning is invoked...");
		System.out.println("Called by : " + joinPoint.getSignature().getName());
		System.out.println("Returned value : " + resultValue);
	}
}

35.aspectj.xml

<aop:after-returning> tag’inda method olarak AuditServiceAspect#logAfterReturning ‘i kullaniyoruz.
returning attribute olarak “resultValue” yazdik , bu deger ile logAfterReturning metodundaki String resultValue ayni isimde olduguna dikkat edelim.

	<aop:config>
		<aop:aspect id="myaspect" ref="auditServiceAspectId">

			....
			
			<!-- AfterReturning -->
			<aop:pointcut id="pointCutAfterReturningId" expression="execution(* *.getEmployeeId(..))" />
			<aop:after-returning method="logAfterReturning" returning="resultValue" pointcut-ref="pointCutAfterReturningId" />
			
		</aop:aspect>
	</aop:config>

EmployeeService.java

getEmployeeId metodu geriye String donmektedir.

package _35.aspectj.service;

public class EmployeeService {

	....
	....

	public String getEmployeeId() {
		// AuditServiceAspect#logAfterReturning will be invoked "after-returning"
		System.out.println("getEmployeeId is invoked...");
		return "Emp-1000";
	}
}

AspectJTest.java

public class AspectJTest {

	public static void main(String[] args) {
        ......
		// aop:before

		// aop:after-returning
		employeeService.getEmployeeId();
        ....
        ////
        }
}

Ornegimizi calistirdigimizda ;
getEmployeeId metodu calistiktan sonra logAfterReturning metodu calisti.

getEmployeeId is invoked...
logAfterReturning is invoked...
Called by : getEmployeeId
Returned value : Emp-1000

<aop:after-throwing>

<aop:after-throwing> yaklasiminda bir Exception firlatildigi durumlarda kullanisli olacaktir.

EmployeeService.java

package _35.aspectj.service;

public class EmployeeService {

	///
	//....
	public void deleteEmployee() {
		// AuditServiceAspect#logAfterThrowing will be invoked "after-throwing"
		System.out.println("deleteEmployee is invoked...");
		throw new RuntimeException();
	}
}

AuditServiceAspect.java

package _35.aspectj.service;

import org.aspectj.lang.JoinPoint;

public class AuditServiceAspect {
	
	///
	///

	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);

	}

}

35.aspectj.xml

<aop:throwing> tag’inda throwing attribute’te kullandigimiz isim ile logAfterThrowing metodunda kullandigimiz Exception parametresi ayni isim olduguna dikkat edelim.

<aop:config>
	<aop:aspect id="myaspect" ref="auditServiceAspectId">

	///
	....
		
		<!-- AfterThrowing -->
		<aop:pointcut id="pointCutAfterThrowingId" expression="execution(* *.deleteEmployee(..))" />
		<aop:after-throwing method="logAfterThrowing" throwing="thrownException" pointcut-ref="pointCutAfterThrowingId"  />
		
	</aop:aspect>
</aop:config>

AspectJTest.java

public class AspectJTest {

	public static void main(String[] args) {
		....

		System.out.println();

		// aop:after-throwing
		try {
			employeeService.deleteEmployee();
		} catch (Exception e) {

		}
				
	}
}

Ornegimizi calistirdigimizda ;
deleteEmployee metodu calistiktan sonra RuntimeException firlatiyoruz.
Exception firlatildigi icin logAfterThrowing metodu calisacaktir.

deleteEmployee is invoked...
logAfterThrowing is invoked...
Called by  : deleteEmployee
Exception : java.lang.RuntimeException

<aop:around>

Son olarak <aop:around> yaklasimini kullanalim. logAround metodumuzda ProceedingJoinPoint parametresi kullaniyoruz ve proceed metodunu calistiriyoruz.

EmployeeService.java

package _35.aspectj.service;

import java.util.List;

public class EmployeeService {
	....
	....
	public List<Object> getAllEmployees() {
		System.out.println("getAllEmployees is invoked...");
		//
		return null;
	}
}

AuditServiceAspect.java

package _35.aspectj.service;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class AuditServiceAspect {

	///
	///
	...

	public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

		System.out.println("logAround is invoked...");
		System.out.println("Called by : " + joinPoint.getSignature().getName());
		System.out.println("Around before is running!");

		joinPoint.proceed();

		System.out.println("Around after is running!");
		
	}
}

35.aspectj.xml

<aop:config>
	<aop:aspect id="myaspect" ref="auditServiceAspectId">

		<!-- Around -->
		<aop:pointcut id="pointCutAround" expression="execution(* *.getAllEmployees(..))" />
		<aop:around method="logAround" pointcut-ref="pointCutAround"  />
		
	</aop:aspect>
</aop:config>

AspectJTest.java

//....
public class AspectJTest {

	public static void main(String[] args) {

		//...
		...
		
		System.out.println();
		
		//aop:around		
		employeeService.getAllEmployees();		
		
		
	}
}

Ornegimizi calistirdigimizda getAllEmployees metodundan once logAround metodu calismaktadir. proceed metodunu cagirdigimiz noktadan sonra getAllEmployees metodu calismakta sonrasinda logAround metodu calismasina kaldigi yerden devam etmektedir.

logAround is invoked...
Called by : getAllEmployees
Around before is running!
getAllEmployees is invoked...
Around after is running!

Github kaynak dosyalar/ source folder
leventerguder/injavawetrust-spring-tutorial

Yazimi burada sonlandiriyorum.
Herkese bol Javali gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer

Print Friendly, PDF & Email

Leave a Reply

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