Aspect Oriented Programming answers cross-cutting concern.Cross-cutting concern is one that can affect the whole application and should be centralized in one location in code as possible, such as transaction management, authentication, logging, security etc.

Aspect – A module which has a set of APIs providing cross-cutting requirements. For example, a logging module would be called AOP aspect for logging. An application can have any number of aspects depending on the requirement.

Advice – This is the actual action to be taken either before or after the method execution. This is actual piece of code that is invoked during program execution by Spring AOP framework.

LoggingAspect.java

package com.mugil.shapes;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect 
{
	@Before("execution(public String getName())")
	public void loggingAdvice()
	{
		System.out.println("This is Logging Advice");
	}
}

DrawingApp.java

package com.mugil.shapes;

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

public class DrawingApp 
{
	public static void main(String[] args) 
	{
		ApplicationContext objContext = new ClassPathXmlApplicationContext("Spring-Customer.xml");
		ShapeService  objCircle = (ShapeService) objContext.getBean("shapeService", ShapeService.class);
		System.out.println(objCircle.getObjCircle().getName());
System.out.println(objCircle.getObjTriangle().getName());
	}
}

Circle.java

package com.mugil.shapes;

public class Circle {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
}

Triangle.java

package com.mugil.shapes;

public class Triangle {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}	
}

Output

This is Logging Advice
Circle Name
This is Logging Advice
Triangle Name

@Before(“execution(public String getName())”)
Applies for all the methods with getName() signature (Triangle and Circle Class)

Output

This is Logging Advice
Circle Name
This is Logging Advice
Triangle Name

@Before(“execution(public String com.mugil.shapes.Circle.getName())”)
Applies for the methods with getName() signature (Circle Class)

Output

This is Logging Advice
Circle Name

@Before(“execution(public String com.mugil.shapes.*.getName())”)
Applies for getName() method in Triangle and Circle Class

Output

This is Logging Advice
Circle Name
This is Logging Advice
Triangle Name

@Before(“execution(public * get*())”)
Applies for all getters method in Triangle,Circle and ShapeService Class

Output

This is Logging Advice
This is Logging Advice
Circle Name
This is Logging Advice
This is Logging Advice
Triangle Name

@Before(“execution(public String getName(*))”)
Applies to all getName() method with one or more argument.

@Before(“execution(public String getName(..))”)
Applies to all getName() method with zero or more argument.

Pointcut – This is a set of one or more joinpoints where an advice should be executed. You can specify pointcuts using expressions or patterns as we will see in our AOP examples.

DrawingApp.java

package com.mugil.shapes;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect 
{	
	@Before("allGetters()")
	public void loggingAdvice1()
	{
		System.out.println("This is Logging Advice 1");
	}
	
	@Before("allGetters()")
	public void loggingAdvice2()
	{
		System.out.println("This is Logging Advice 2");
	}
		
	@Pointcut("execution(* getName())")
	public void allGetters()
	{	
	}
}
  1. allGetters() method will be called when ever the getName() method of Circle (or) Triangle gets called
  2. Before allGetters() method gets called the loggingAdvice1() and loggingAdvice2() method gets called.

Output

This is Logging Advice 1
This is Logging Advice 2
Circle Name
 @Pointcut("execution(* com.mugil.shapes.*.get*(..))")

Applies for all the Getters within shapes package

 @Pointcut("execution(public * com.mugil.shapes.*.get*(..))")

Applies for all the Public Getters within shapes package

 @Pointcut("within(com.mugil.shapes.*)")

within applies for everything within class whereas execution applies only to the methods.

Runs for all methods getters and setters in com.mugil.shapes.* package.

@Pointcut("args(..)")

Runs for all methods getters and setters.

Join point – This represents a point in your application where you can plug-in AOP aspect. You can also say, it is the actual place in the application where an action will be taken using Spring AOP framework.

Using JoinPoint we can have access to the Object in the advice method.

LoggingAspect.java

package com.mugil.shapes;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect
public class LoggingAspect {
	
	@Before("allGetters()")
	 public void LogginAdvice(JoinPoint joinpoint)
    {
		System.out.println("advice is run");
	    System.out.println(joinpoint.toString());
    }
	
	@Before("args(name)")
	public void LoggingAdvice2(String name)
	{
		System.out.println("-- " + name);
	}
	
	@Pointcut("execution(* com.mugil.shapes.*.get*())")
	public void allGetters()
	{	
	}
}

DrawingApp.java

public class DrawingApp {
	public static void main(String[] args) {
		ApplicationContext objContext = new ClassPathXmlApplicationContext("Spring-Customer.xml");
		ShapeService  objCircle = (ShapeService) objContext.getBean("shapeService", ShapeService.class);
objCircle.getObjTriangle().setName("Test Tri");
		System.out.println(objCircle.getObjTriangle().getName());	
	}
}

Output

advice is run
execution(Triangle com.mugil.shapes.ShapeService.getObjTriangle())
-- Test Tri
advice is run
execution(Triangle com.mugil.shapes.ShapeService.getObjTriangle())
advice is run
execution(String com.mugil.shapes.Triangle.getName())
Test Tri

LoggingAspect.java

@Aspect
public class LoggingAspect {
	
	@Before("allGetters()")
	 public void LogginAdvice(JoinPoint joinpoint)
    {
		System.out.println("advice is run");
	    System.out.println(joinpoint.toString());
    }
	
	@AfterReturning(pointcut ="args(name)", returning="returnString")
	public void LoggingAdvice2(String name, String returnString)
	{
		System.out.println("This is Input to Method " + name);
		System.out.println("This is Returned  from  Method " + returnString);
	}
	
	@AfterThrowing(pointcut="args(name)", throwing="ex")
	public void LoggingAdvice4(String name, RuntimeException ex)
	{
		System.out.println("This will be Printed incase of Exception is Thrown in Method");		
		System.out.println(ex);
	}

	
	@Pointcut("execution(* com.mugil.shapes.*.get*())")
	public void allGetters()
	{	
	}
}

Using Around

@Around("allGetters()")
	public void LoggingAdvice2(ProceedingJoinPoint pjp)
	{
		Object objObject = null;		
		
		try {
			System.out.println("Code before Method Execution Goes here");			
			objObject = pjp.proceed();
			System.out.println("Code after Method Execution Goes here");
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
Posted in AOP.

Comments are closed.