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