Backend Development 14 min read

Spring AOP Tutorial: Concepts, XML Configuration, and Sample Implementation

This article explains Aspect‑Oriented Programming (AOP) as a complement to OOP, introduces core AOP concepts such as aspects, join points, pointcuts, advice, weaving and introductions, and provides a step‑by‑step Spring XML configuration with Java code examples demonstrating time‑logging and logging aspects, ordering, selective pointcuts, and forced CGLIB proxy usage.

Java Captain
Java Captain
Java Captain
Spring AOP Tutorial: Concepts, XML Configuration, and Sample Implementation

Aspect‑Oriented Programming (AOP) is a programming paradigm that complements Object‑Oriented Programming (OOP) by allowing cross‑cutting concerns such as logging, security, and transaction management to be modularized into reusable components called aspects.

In OOP, encapsulation, inheritance, and polymorphism model vertical relationships, but they do not handle horizontal concerns that are scattered across many classes, leading to code duplication. AOP solves this by extracting these concerns into aspects, reducing repetition and coupling.

AOP divides a system into two parts: the core concern (the main business logic) and the cross‑cutting concern (the aspect). The framework intercepts method executions (join points) defined by pointcuts and applies advice (before, after, around, after‑returning, after‑throwing) to them.

Core AOP concepts

Cross‑cutting concern – functionality that cuts across multiple modules (e.g., logging).

Aspect – a modularization of a cross‑cutting concern.

Join point – a point in the program execution where an aspect can be applied (in Spring, typically a method execution).

Pointcut – an expression that selects join points.

Advice – the code to execute at a selected join point (before, after, around, etc.).

Target object – the original object being proxied.

Weaving – the process of applying aspects to target objects to create proxy objects.

Introduction – adding new methods or fields to existing classes without modifying their source.

Spring’s support for AOP

Spring’s IoC container creates and manages AOP proxies. By default Spring uses JDK dynamic proxies for interfaces; if a class does not implement an interface, Spring falls back to CGLIB (or can be forced to use CGLIB with proxy-target-class="true" ).

Typical AOP programming steps in Spring:

Define regular business components (e.g., HelloWorld interface and its implementations).

Define a pointcut that matches the methods to be intercepted.

Define advice that contains the additional behavior.

When both pointcut and advice are defined, Spring automatically creates a proxy so that the method execution becomes advice + original method .

Sample XML configuration (aop.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"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
                           http://www.springframework.org/schema/aop
                           http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">

    <bean id="helloWorldImpl1" class="com.xrq.aop.HelloWorldImpl1"/>
    <bean id="helloWorldImpl2" class="com.xrq.aop.HelloWorldImpl2"/>
    <bean id="timeHandler" class="com.xrq.aop.TimeHandler"/>

    <aop:config>
        <aop:aspect id="time" ref="timeHandler" order="1">
            <aop:pointcut id="addAllMethod" expression="execution(* com.xrq.aop.HelloWorld.*(..))"/>
            <aop:before method="printTime" pointcut-ref="addAllMethod"/>
            <aop:after method="printTime" pointcut-ref="addAllMethod"/>
        </aop:aspect>
    </aop:config>
</beans>

Java code examples

Interface definition:

public interface HelloWorld {
    void printHelloWorld();
    void doPrint();
}

Two implementations:

public class HelloWorldImpl1 implements HelloWorld {
    public void printHelloWorld() {
        System.out.println("Enter HelloWorldImpl1.printHelloWorld()");
    }
    public void doPrint() {
        System.out.println("Enter HelloWorldImpl1.doPrint()");
    }
}

public class HelloWorldImpl2 implements HelloWorld {
    public void printHelloWorld() {
        System.out.println("Enter HelloWorldImpl2.printHelloWorld()");
    }
    public void doPrint() {
        System.out.println("Enter HelloWorldImpl2.doPrint()");
    }
}

Time‑logging aspect class:

public class TimeHandler {
    public void printTime() {
        System.out.println("CurrentTime = " + System.currentTimeMillis());
    }
}

Main method to run the example (requires aopalliance.jar and aspectjweaver.jar in the classpath):

public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("aop.xml");
    HelloWorld hw1 = (HelloWorld) ctx.getBean("helloWorldImpl1");
    HelloWorld hw2 = (HelloWorld) ctx.getBean("helloWorldImpl2");
    hw1.printHelloWorld();
    System.out.println();
    hw1.doPrint();
    System.out.println();
    hw2.printHelloWorld();
    System.out.println();
    hw2.doPrint();
}

The output shows the current time printed before each method execution, demonstrating that the time‑logging aspect has been woven into both implementations.

Adding a logging aspect

Define a new aspect class:

public class LogHandler {
    public void LogBefore() {
        System.out.println("Log before method");
    }
    public void LogAfter() {
        System.out.println("Log after method");
    }
}

Update aop.xml to include the logging aspect, set the order attribute to control execution order (lower order runs first), and define separate pointcuts for time‑logging and logging:

... (full XML shown in the source, now containing two
elements with ids "time" and "log") ...

Running the updated configuration prints log messages before and after the time messages, confirming the ordering.

Selectively weaving methods

Modify the pointcut expression, e.g., execution(* com.xrq.aop.HelloWorld.print*(..)) to apply the time aspect only to methods whose names start with print , and execution(* com.xrq.aop.HelloWorld.do*(..)) for the logging aspect.

Forcing CGLIB proxy generation

Set proxy-target-class="true" in the aop:config element; this forces Spring to use class‑based CGLIB proxies even when interfaces are present.

Original source attribution: cnblogs.com/xrq730/p/4919025.html.

JavaaopSpringAspect-Oriented ProgrammingCGLIBXML ConfigurationCross-Cutting Concerns
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.