< Prev
Next >



Spring with AspectJ by DTD



In this tutorial, we are going to explain how to configure the Spring Framework to work with AspectJ using dtd provided by Spring Framework. For this, we are going to use interfaces and classes declared in org.springframework.aop package, used to specify the aspects by specifying its elements - jointcut, pointcut and advices within a configuration xml file, instead of declaring these AspectJ properties within a Java class(as we did in our previous tutorial to configure Spring with AspectJ using AspectJ Annotations).




Creating the Java class - MarathonRunner


We are going to create a java class named MarathonRunner within the decodejava package and this class contains - Besides this, we are also going to define a couple of getter and setter methods within this class to set the above mentioned properties of MarathonRunner class.

Besides these getter and setter and methods, we are going to define two more methods i.e. marathonBegins() and marathonEnds(), which are going to become our joinpoints. Before the execution of these methods(joinpoints), we are going to apply the pointcuts and advices of AspectJ(specified in xml configuration file), later on.


package decodejava;

public class MarathonRunner
{
String name;
int age;

//Getter method for age
public int getAge() {
	return age;
}

//Setter method for age
public void setAge(int age) {
	this.age = age;
}


//Getter method for name
public String getName()
{
	return name;
}

//Setter method for name
public void setName(String name) 
{
	this.name = name;
}

public void marathonBegins()
{
System.out.println("Marathon runner has started the race");
}

public void marathonEnds()
{
System.out.println("Marathon runner has finished the race");
}

}





Class defining pointcut and advices


Next, we are going to add another Java class named MarathonTimeTracker by implementing a few important interfaces declared in org.springframework.aop and org.aopalliance.intercept packages, such as -

Interface Description
MethodBeforeAdvice This interface is used to specify before advice.
AfterReturningAdvice This interface is used to specify after-returning advice.
MethodInterceptor This interface is used to intercept a call to joinpoint.



package decodejava;

import java.lang.reflect.Method;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;


public class MarathonTimeTracker implements MethodInterceptor, MethodBeforeAdvice, AfterReturningAdvice
{
	MethodInvocation me;
	
	public void trackingBegins()
	{
	System.out.println("Marathon has started");
	System.out.println("Tracking the marathon has begun");
	}


	public void trackingEnds()
	{
	System.out.println("Marathon has ended");
	System.out.println("Tracking the marathon has ended");
	}


	@Override
	public void afterReturning(Object arg0, Method method, Object[] arg2, Object arg3) throws Throwable 
	{
		if("marathonEnds".equals(me.getMethod().getName()))
		{
			System.out.println("After Method - " + method.getName());
			trackingEnds();	
		}		
	}


	@Override
	public void before(Method method , Object[] arg1, Object arg2)	throws Throwable 
	{
		if("marathonBegins".equals(me.getMethod().getName()))
		{
			System.out.println("Before Method - " + method.getName());
			trackingBegins();	
		}
	}


	@Override
	public Object invoke(MethodInvocation me) throws Throwable 
	{
		this.me = me;
		return me.proceed();
	}



}


MarathonTimeTracker class has implemented MethodBeforeAdvice and MethodInterceptor interfaces, which allows us to -




Adding the Utility class that calls the Spring API


Next, we are going to create another class named - Utility, which is a simple java class.

Utility.java
package decodejava;	

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

public class Utility
{
public static void main(String[] ar)
{
	
	ApplicationContext context = new FileSystemXmlApplicationContext("classpath:config.beans.xml");
	MarathonRunner mr = context.getBean("MarathonBean", MarathonRunner.class);
	System.out.println("Name of the Marathon Runner - " + mr.getName());
	System.out.println("Age of the Marathon Runner - " + mr.getAge());
	mr.marathonBegins();
	mr.marathonEnds();
}
}


The Utility class uses the ApplicationContext container(an interface) of Spring Framework by creating its instance using its implemented class FileSystemXmlApplicationContext, which loads the configuration xml file - config.beans.xml and does the following -






Adding a configuration file


Next, we are going to add a configuration file to our project. This configuration document is an Extensible Markup Language(XML) file, ending with .xml extension and we are going to name this file as config.beans.xml.


config.beans.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:util="springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       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/context
       https://www.springframework.org/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       ">


    
<bean id="MarathonRunnerBean" class="decodejava.MarathonRunner">
<property name="name" value="Runner1"></property>
<property name="age" value="27"></property>
</bean>

<bean id="MarathonTimeTrackerAdvisorBean" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="mappedNames" value="marathonEnds,marathonBegins"></property>
<property name="advice">
	<bean class="decodejava.MarathonTimeTracker"></bean>
</property>
</bean>

<bean id="MarathonBean" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="MarathonRunnerBean"></property>
<property name="interceptorNames" value="MarathonTimeTrackerAdvisorBean"></property>
</bean>


</beans>



In order to make this Spring project work with AspectJ using schema provided by Spring, we have included an http://www.springframework.org/schema/aop namespace within this configuration file and have used the classes declared in org.springframework.aop package, such as -

Class Description
ProxyFactoryBean This class allows us to create a proxy class in whic we have defined the pointcut and advices.
NameMatchMethodPointcut This class takes the name of the methods as pointcut.



This mapping document has a parent <beans> tag as the root element and its individual child elements, where each child element stats with a <bean> tag, containing all the attributes such as -


  1. In this file, we have configured a MarathonRunner bean with a unique id i.e. MarathonRunnerBean and its properties named name and age. These properties will be assigned a value by the Spring Container using their respective setter methods, when the MarathonRunner bean is created by it, using the configuration xml file.



  2. We have also configured a NameMatchMethodPointcutAdvisor bean with its two child properties using the property child element, for example -




  3. Next, we have also configured a bean of ProxyFactoryBean class, which creates the proxy class for the target class MarathonRunner at the runtime and provide the aspect oriented support. This bean has two child properties using the property child element, for example -





Adding JARs



Directory Structure of Project




The picture above depicts how and where to arrange classes and interfaces comprising this Spring Project, in a specific directory structure.

Project Folder - SpringWithAspectJByDtd is the name of our Project and it is a top-level directory.






Execution


Finally, after executing the Utility class, you will get the following output within the Console window. This output displayed below shows, how the Utility class has used the ApplicationContext container of Spring Framework to load the configuration xml file - config.beans.xml, in order to access the beans specified in it, instantiate the MarathonRunner class.

Whenever the method of MarathonRunner are called, the pointcuts and advices tracking them are called and their associated methods of MarathonTimeTracker of class are executed(configured in xml).


Aug 07, 2018 12:00:47 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.FileSystemXmlApplicationContext@5e91993f: startup date [Tue Aug 07 12:00:47 2018]; root of context hierarchy
Aug 07, 2018 12:00:48 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [config.beans.xml]
Before Method - marathonBegins
Marathon has started
Tracking the marathon has begun
Marathon runner has started the race
Marathon runner has finished the race
After Method - marathonEnds
Marathon has ended
Tracking the marathon has ended


And, this concludes configuring Spring Framework with AspectJ using dtd provided by Spring Framework using its important classes declared in org.springframework.aop package.




Please share this article -




< Prev
Next >
< Spring-AspectJ with Schema
Spring Expression Language(SpEL) >
Please subscribe our social media channels for notifications, we post a new article everyday.

Decodejava Google+ Page Decodejava Facebook Page  DecodeJava Twitter Page

Coming Next
-
C++ and Python

Ad2