Spring Aspect with Annotations

Aspect defines the implementation of cross-cutting concern. We implement a cross-cutting functionality by creating an aspect. Aspect encapsulates our cross-cutting concern. There are two ways to define aspects in Spring. One is schema based(regular java class and configuration in spring configuration file ) and other in annotation based (regular java class with annotation @Aspect) . An aspect contains pointcut and advice body.

Spring Aspects:
   1) Pre defined aspects: Can use it for spring transaction management.
   2) Custom aspect: To perform common logic.

Will create custom aspect and will check how this wil work...

Using custom Aspect can perform some common logic for specif layer or specific class or specific application.

Example:
    1) Convertng to custom exception, if we get any exception.
    2) Loggings.

This is my actual class, will apply aspect on this class will see how aspect will work.

package com.javavillage.annotate;

import org.springframework.stereotype.Component;

@Component("inst")
public class Instrumentalist {
	public void play()
	{
		System.out.println("Playing instrument");
		//throw new RuntimeException("problem with instrument");
	}

}


Below class is my aspect, Here observations for aspect annotations:

@Aspect: indicates class is aspect.
@Before: Executes before play method
@After: Executes after the method returned a result
@AfterReturning:  Executes after play method
@Around: Executes around the method execution, combine all three advices above.
@AfterThrowing:Executes after play method if any exception comes


Note: Aspect nothing but will surround actual execution, can useful to execute some common logic based on the response from class.
.
package com.javavillage.annotate;

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class Audience {
	@Before("execution (* com.javavillage.annotate.*.*(..))")
	public void takeSeats()
	{
		System.out.println("taking seats");
	}
	@Before("execution (* com.javavillage.annotate.*.*(..))")
	public void switchOffMobilePhones()
	{
		System.out.println("switching off mobile phones");
	}
	@AfterReturning("execution (* com.javavillage.annotate.*.*(..))")
	public void applaud()
	{
		System.out.println("clapping");
	}
	@AfterThrowing("execution (* com.javavillage.annotate.*.*(..))")
	public void demandRefund()
	{
		System.out.println("demanding refund");
	}

}


Below is aopContext.xml: configuartion file for spring. Already I am having annotation, why I need context file. We can avoid context file maximum not fully, mandatory we have to specify some details to make sure aspect and annotations to get enable.

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

	<context:component-scan base-package="com.javavillage.annotate"></context:component-scan>
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

context:component-scan: To enable annotations for specifuc package
aop:aspectj-autoproxy: To enable aspect for applications



Maven entries for pom.xml

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>3.2.8.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>3.2.8.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>3.2.8.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>3.2.8.RELEASE</version>
		</dependency>

		<dependency>
			<groupId>aopalliance</groupId>
			<artifactId>aopalliance</artifactId>
			<version>1.0</version>
		</dependency>

		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.7.4</version>
		</dependency>



Below is my application execution

package com.javavillage;

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

import com.javavillage.annotate.Instrumentalist;


/**
 * Hello world!
 *
 */
public class App 
{
    public static void main( String[] args )
    {
       ApplicationContext ctx=new ClassPathXmlApplicationContext("aopContext.xml");
       Instrumentalist instrumentalist=(Instrumentalist)ctx.getBean("inst");
       instrumentalist.play();
    }
}


Spring Aspect Application structure:

Spring Aspect Application structure

Execute Spring Aspect Application:

Execution Spring Aspect Application

throw new RuntimeException("problem with instrument"); from Instrumentalist and see how @AfterThrowing annotated method will get executed from Aspect class(Audience.java).

Spring Aspect execution with return Exception