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
Leave a Reply