#
Spring ProceedingJoinPoint (explanation & example)
This tutorial gives you a short explanation of the Spring Pointcut concept and provides you with a simple-to-understand example with the ProceedingJoinPoint parameter.
Aspect-Oriented Programming (AOP) complements Object-Oriented Programming (OOP) by providing another way of thinking about program structure. The key unit of modularity in OOP is the class, whereas in AOP the unit of modularity is the aspect. Aspects enable the modularization of concerns such as transaction management that cut across multiple types and objects.
An aspect class, contains 2 things:
a
Pointcut
: where to do something (a cross-cutting concern). A Pointcut is a predicate that matches join points. A pointcut, could have many advice types: before, after, after returning, after throwing, around. A pointcut could be defined separately. You can take a look at the article named Spring Pointcut annotation (explanation & example).an
Advice
: WHAT TO DO at that join point/pointcut. This is a method defined under the Pointcut.
One of the key concept in the AOP is the ProceedingJoinPoint. ProceedingJoinPoint exposes the proceed()
method
in order to support around
advice type.
In order to create an AOP example using a ProceedingJoinPoint
parameter, you have to create a Spring Maven simple project.
After that you have to add the following dependencies into the pom.xml file:
After that you have to create the following classes:
package com.example.aspects;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class MyAspect {
@Pointcut("execution(* com.example.services.MyService1.methodA(..))")
public void onePointcut() {}
@Around("onePointcut()")
public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("This will run BEFORE methodA()");
pjp.proceed();
System.out.println("This will run AFTER methodA()");
}
}
package com.example.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.example.aspects.MyAspect;
import com.example.services.MyService1;
@Configuration
@EnableAspectJAutoProxy
public class SpringContextConfig {
@Bean
public MyService1 myService() {
return new MyService1();
}
@Bean
public MyAspect myAspect() {
return new MyAspect();
}
}
package com.example.services;
public class MyService1 {
public void methodA() {
System.out.println("MyService1 is running methodA() ...");
}
}
package com.example.main;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.example.config.SpringContextConfig;
import com.example.services.*;
public class Main {
public static void main (String [] args) {
System.out.println("Start Java Application ...");
//The Spring context is configured from a Java Class for a Java Application
// (Not for a Web Application)
// FileSystemXmlApplicationContext --> used when the context is defined in an xml file.
try (AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(SpringContextConfig.class)) {
System.out.println("Spring context created ...");
//GET an instance from context BY CLASS
// SINGLETON by default in Spring
MyService1 myService1 = context.getBean(MyService1.class);
myService1.methodA();
}
}
}
When you run the project you must see something like that: