Spring AOP Before Advice example using XML configuration


This page will walk through the Spring AOP before advice example using XML configuration file. Spring provides an interface MethodBeforeAdvice which help you to invoke your service, logging, transactions, etc before a method is invoked. Such advice cannot prevent the method call proceeding unless they throw a Throwable.

Interface MethodBeforeAdvice contains only one method.

void before(Method method, Object[] args, @Nullable Object target) throws Throwable;

In this example, we have a deposit method in Bank class and I want to print some logging message before executing the deposit method.

Let’s see the complete example.

Business Class

Create a Bank class that has two parameters String accountNumber, int amount and a deposit method which will add the amount to the accountNumber.

Bank.java
package org.websparrow.business;

import org.websparrow.exception.InvalidAccountNumberException;

public class Bank {

	private String accountNo = "XYZ123";
	private int amount = 1000;

	public int deposit(int amount, String acNo) {

		if (acNo.equals(this.accountNo)) {

			System.out.println("inside deposite method...");

			this.amount = this.amount + amount;
			return this.amount;

		} else {
			throw new InvalidAccountNumberException();
		}
	}
}

Exception Class

Create a class InvalidAccountNumberException that handles the exception when accountNumber does not match and it throws INVALID ACCOUNT NUMBER.

InvalidAccountNumberException.java
package org.websparrow.exception;

public class InvalidAccountNumberException extends RuntimeException {

	private static final long serialVersionUID = 9087720614302482902L;

	@Override
	public String toString() {

		return "INVALID ACCOUNT NUMBER";
	}
}

Service Class

Create a service class LoggingService that implements MethodBeforeAdvice interface and override it’s before method.

LoggingService.java
package org.websparrow.service;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class LoggingService implements MethodBeforeAdvice {

	public void before(Method method, Object[] param, Object target) throws Throwable {

		System.out.println("............I'M EXECUTED BEFORE DEPOSITE METHOD................... ");

	}
}

XML Configuration

In the configuration file, instantiate the target class i.e. Bank and advice class i.e. LoggingService and finally add the target + advice to the proxy class i.e. ProxyFactoryBean .

spring.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- create target -->
	<bean id="b" class="org.websparrow.business.Bank" />

	<!-- create advice -->
	<bean id="ls" class="org.websparrow.service.LoggingService" />

	<!-- add target + advice to proxy -->
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="b" />
		<property name="interceptorNames">
			<list>
				<value>ls</value>
			</list>
		</property>
	</bean>
</beans>

The ProxyFactoryBean class is provided by Spring Framework. It contains two properties target and interceptorNames. The instance of Bank class will be considered as the target object and the instance of LoggingService class as an interceptor. You need to pass the LoggingService object as the list object.

Run it

Create a Client class, load the configuration file and runt it.

Client.java
package org.websparrow.test;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.websparrow.business.Bank;

public class Client {

	public static void main(String[] args) {

		ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

		Bank bank = (Bank) context.getBean("proxy");

		int amt = bank.deposit(600, "XYZ123");
		System.out.println("Balance: " + amt);

		context.close();
	}
}
Output:

On your console log, you can see the LoggingService executed before executing the deposit method.

INFO: Loading XML bean definitions from class path resource [spring.xml]
............I'M EXECUTED BEFORE DEPOSITE METHOD................... 
inside deposite method...
Balance: 1600

Programmatic Approach

You can do it without using the XML configuration file. Just replace the Client class with below class.

Test.java
package org.websparrow.test;

import org.springframework.aop.framework.ProxyFactoryBean;
import org.websparrow.business.Bank;
import org.websparrow.service.LoggingService;

public class Test {

	public static void main(String[] args) {

		// create target
		Bank b = new Bank();

		// create advice
		LoggingService ls = new LoggingService();

		// add target + advice to proxy
		ProxyFactoryBean proxy = new ProxyFactoryBean();
		proxy.setTarget(b);
		proxy.addAdvice(ls);

		// get generated proxy object
		Bank bproxy = (Bank) proxy.getObject();
		int amount = bproxy.deposit(500, "XYZ123");

		System.out.println(amount);
	}
}

Similar Posts

About the Author

Websparrow
I like sharing my experiments and ideas with everyone by writing articles on the latest technological trends.