25 May 2015

Introduction

Spring AOP can take control and add some additional functionalities before and after the methods getting executed.
In this example AOP implementations are provided by

  • AspectJ
  • Spring AOP

Required Software

  • JDK 1.7
  • Maven 2.2.x
  • Eclipse for J2EE

Steps to write code

Below example shows the implementation of Joint point, Advice and Pointcut

Project Structure is shown below

  • pom.xml:
 
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>SpringAOPExample</groupId>
	<artifactId>SpringAOPExample</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<spring.version>4.0.1.RELEASE</spring.version>
		<aspectj.version>1.7.4</aspectj.version>
	</properties>

	<build>
		<sourceDirectory>src</sourceDirectory>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>

	<dependencies>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- This dependancy is required for spring ApplicationContext container -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		
		<!-- Spring AOP dependency -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- AspectJ 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>
</project>
  • spring-config.xml: <aop:aspectj-autoproxy /> element is required for enabling Spring AOP support.

<?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: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-3.0.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/aop
  http://www.springframework.org/schema/aop/spring-aop.xsd">

	<context:component-scan base-package="com.ashish" />

	<!-- This element is required for enabling Spring AOP support -->
	<aop:aspectj-autoproxy />
	
	<bean id="loggingAspect" class="com.ashish.aop.LoggingAspect">
	</bean>
	
	<!-- Spring AOP applied on the methods available in this service -->
	<bean id="springServices" class="com.ashish.services.SpringServices">
	</bean>

</beans>
  • SpringServices.java: AOP is implemented on this service class

package com.ashish.services;

public class SpringServices {
	
	public void aMethod() {
		System.out.println("Inside aMethod()");
	}

	public String returningAdvice() {
		System.out.println("Inside returningAdvice");
		return new String("Hello world from returningAdvice");
	}

	public void throwsAdvice() {
		System.out.println("Inside throwsAdvice");
		throw new RuntimeException("Exception from throwsAdvice");
	}

	public String testAroundAdvice() {
		System.out.println("Inside testAroundAdvice");
		return new String("Hello world from testAroundAdvice");
	}

	public void testAroundThrowingExceptionAdvice() throws Exception {
		System.out.println("Inside testAroundThrowingExceptionAdvice");
		throw new RuntimeException("Exception from testAroundThrowingExceptionAdvice");
	}
}

  • LoggingAspect.java: implementation of Joint point, Advice and Pointcut done in this class

package com.ashish.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LoggingAspect {

	@Before("execution(* com.ashish.services.SpringServices.aMethod(..))")
	public void beforeExecution(JoinPoint jp) {
		System.out.println("Before method: " + jp.getSignature().getName()
				+ ". Class: " + jp.getTarget().getClass().getSimpleName());
	}

	@After("execution(* com.ashish.services.SpringServices.aMethod(..))")
	public void afterExecution(JoinPoint jp) {
		System.out.println("After method: " + jp.getSignature().getName()
				+ ". Class: " + jp.getTarget().getClass().getSimpleName());
	}
	
	@AfterReturning(pointcut = "execution(* com.ashish.services.SpringServices.returningAdvice(..))", returning = "result")
	public void afterReturningExecution(JoinPoint jp, Object result) {
		System.out.println("After returning advice: "
				+ jp.getSignature().getName() + ". Class: "
				+ jp.getTarget().getClass().getSimpleName());
		System.out.println("Advice returned: " + result);
	}

	@AfterThrowing(pointcut = "execution(* com.ashish.services.SpringServices.throwsAdvice(..))", throwing = "ex")
	public void afterThrowingExecution(JoinPoint jp, Exception ex) {
		System.out.println("After throwing advice: "
				+ jp.getSignature().getName() + ". Class: "
				+ jp.getTarget().getClass().getSimpleName());
		System.out.println("Exception: " + ex.getMessage());
	}

	@Around("execution(* com.ashish.services.SpringServices.testAround*(..))")
	public Object aroundExecution(ProceedingJoinPoint jp) throws Exception {

		System.out.println("Before method: " + jp.getSignature().getName()
				+ ". Class: " + jp.getTarget().getClass().getSimpleName());

		try {
			// Proceed with method invocation
			Object result = jp.proceed();

			System.out.println("Returning: " + result);
			return result;
		} catch (Throwable e) {
			System.out.println("Error: " + e.getMessage());
			throw new Exception("Error", e);
		}
	}
}
  • MainApp.java: Entry point of the application

package com.ashish;

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

import com.ashish.services.SpringServices;

public class MainApp {
	public static void main(String args[]) {
		ApplicationContext appContext = new ClassPathXmlApplicationContext("spring-config.xml");
		
		SpringServices springServices = (SpringServices) appContext.getBean("springServices");
		
		springServices.aMethod();
		
		System.out.println("===================================\n");
		Object result = springServices.returningAdvice();
		System.out.println("===================================\n");
		try {
			springServices.throwsAdvice();
		} catch (Exception e) {
			System.out.println("Exception caught in MainApp: " + e.getMessage());
		}
		System.out.println("===================================\n");
		result = springServices.testAroundAdvice();
		System.out.println("===================================\n");
		try {
			springServices.testAroundThrowingExceptionAdvice();
		} catch (Exception e) {
			System.out.println("Exception caught in MainApp: " + e.getMessage());
		}
		System.out.println("===================================\n");
	}
}
  • Output of the application is shown below


blog comments powered by Disqus
J2EE,SOAP,RESTful,SVN,PMD,SONAR,JaCoCo,HTTP,API,MAVEN,AngularJS,GitHub,LDAP,AOP,ORM,JMS,MVC,AWS,SQL,PHP,H2DB,JDBC