Search code examples
javaspringmavenaopspring-aop

Spring AOP aop:after running early


I have been trying out Spring's AOP feature lately on a very simple app, and I am stuck with running the method in the propriet time, meaning the method defined in the section should run after the method defined in the

In my code, both the method defined in and ran before the main method. Of course it is normal in but not in the latter one.

The expected output should be:

HERE IS THE AOP BEFORE

From App ran 5k

HERE IS THE AOP After

My current output is:

HERE IS THE AOP BEFORE

HERE IS THE AOP After

From App ran 5k

Any idea why?

Pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>springDemo</groupId>
<artifactId>FirstSpringDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>FirstSpringDemo</name>
<url>http://maven.apache.org</url>
<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
    <sourceDirectory>src</sourceDirectory>
    <plugins>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
                <source>1.8</source>
                <target>1.8</target>
            </configuration>
        </plugin>
    </plugins>
</build>
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>4.3.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>4.3.1.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>3.8.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.11</version>
    </dependency>
</dependencies>
</project>

My main class, called App:

package main.java.springDemo;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
public static void main(String[] args) {

    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    Coach trackCoach = context.getBean("myTrackCoach", Coach.class);

    System.out.println(" From App " + trackCoach.getDailyWorkout());


}
}

TrackerCoach.java

package main.java.springDemo;

public class TrackCoach implements Coach {
@Override
public String getDailyWorkout() {
    return "Go and run 5k";
}
}

SayAOP.java

package main.java.springDemo;


public class SayAOP {

   public void shoutAOPBefore() {

    System.out.println("HERE IS THE AOP BEFORE");
}

public void shoutAOPAfter(){

    System.out.println("HERE IS THE AOP After");
}

}

Coach.java

package main.java.springDemo;

public interface Coach {
    String getDailyWorkout();

}

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

<!-- Define your beans here -->


<aop:config>

    <aop:aspect id="aop" ref="SayAOP">

        <aop:pointcut id="pid" expression="execution(* main.java.springDemo.Coach.getDailyWorkout(..))"/>

        <aop:before pointcut-ref="pid" method="shoutAOPBefore"/>
        <aop:after pointcut-ref="pid" method="shoutAOPAfter"/>
    </aop:aspect>

</aop:config>

<bean id="myTrackCoach"
      class="main.java.springDemo.TrackCoach">

</bean>

<bean id="SayAOP"
      class="main.java.springDemo.SayAOP">
</bean>

</beans>

Solution

  • Thats because trackCoach.getDailyWorkout() is called as System.out.println parameter, so before is called first, then trackCoach.getDailyWorkout() then after, and System.out last. Try for example:

    public class TrackCoach implements Coach {
        @Override
        public String getDailyWorkout() {
            System.out.println("Go and run 5k");
            return "Go and run 5k";
        }
    }
    

    And you will see whats happens.