Implementing Aspect-Oriented Programming with Spring XML Configuration

Configuring AOP Using XML in Spring

Spring supports aspect-oriented programming through both annotations and XML-based configuration. While annotation-driven AOP is more common in modern applications, XML configuration remains a viable and explicit alternative—especially in legacy or highly controlled enviroments.

1. Defining the Aspect Class

The aspect encapsulates cross-cutting concerns such as transaction management, logging, or security checks. Below is an example aspect class that implements five types of advice:

package org.example.aop;

import org.aspectj.lang.ProceedingJoinPoint;

public class TransactionAspect {

    public void startTransaction() {
        System.out.println("[Before] Starting transaction...");
    }

    public void completeTransaction() {
        System.out.println("[After] Committing transaction...");
    }

    public void onSuccess() {
        System.out.println("[AfterReturning] Operation succeeded.");
    }

    public void onException() {
        System.out.println("[AfterThrowing] An error occurred.");
    }

    public void wrapExecution(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("[Around] Before target method...");
        joinPoint.proceed();
        System.out.println("[Around] After target method...");
    }
}

2. Declaring the Target Service Interface and Implementation

A simple service interface and its implementation serve as the target for advice injection:

package org.example.service;

public interface UserService {
    void register();
    void remove();
}
package org.example.service;

public class UserServiceImpl implements UserService {
    @Override
    public void register() {
        System.out.println("[Core] Executing user registration.");
    }

    @Override
    public void remove() {
        System.out.println("[Core] Executing user deletion.");
    }
}

3. Configuring AOP in applicationContext.xml

The XML configuration registers beans and defines pointcuts and advice bindings. Note how pointcut expressions can be reused via pointcut-ref, or declared inline:

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

    <bean id="transactionAspect" class="org.example.aop.TransactionAspect" />
    <bean id="userService" class="org.example.service.UserServiceImpl" />

    <aop:config>
        <!-- Reusable pointcut matching all methods in the service package -->
        <aop:pointcut id="serviceMethods"
                      expression="execution(* org.example.service.*.*(..))" />

        <aop:aspect ref="transactionAspect">
            <aop:around method="wrapExecution" pointcut-ref="serviceMethods" />
            <aop:before method="startTransaction" pointcut-ref="serviceMethods" />
            <aop:after method="completeTransaction" pointcut-ref="serviceMethods" />
            <aop:after-returning method="onSuccess" pointcut-ref="serviceMethods" />
            <aop:after-throwing method="onException" pointcut-ref="serviceMethods" />
        </aop:aspect>
    </aop:config>
</beans>

4. Running the Configuration

To test the setup, load the context and invoke service methods:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.example.service.UserService;

public class AopXmlDemo {
    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService service = ctx.getBean(UserService.class);
        
        service.register();
        service.remove();
    }
}

Expected output includes interleaved core logic and advice messages—demonstrating successful weaving.

5. Pointcut Expression Patterns

Pointcut expressions determine which join points are intercepted. Common patterns include:

  • execution(* *(..)) — All methods in any class.
  • execution(public * *(..)) — All public methods.
  • execution(* save*(..)) — Methods starting with "save".
  • execution(* org.example.service.UserService.register(..)) — Exact method signature.
  • execution(* org.example.service.*.*(..)) — All methods in UserService and other classes in the package.
  • execution(* org.example.service..*.*(..)) — All methods in service and its subpackages.
  • execution(* org.example.service.UserService.register(..)) || execution(* org.example.service.UserService.remove(..)) — Logical OR.
  • !execution(* org.example.service.UserService.remove(..)) — Negation.

These expressions support fine-grained control over where advice applies, enabling modular and maintainable cross-cutting logic.

Tags: Spring aop XML aspect-oriented-programming configuration

Posted on Wed, 15 Jul 2026 16:35:11 +0000 by yaba