[JAVA] How to write Spring AOP pointcut specifier

Overview

This is a summary article on how to write AOP pointcut specifiers. Please note that this article does not cover the details of AOP, Aspect implementation or advice. Please see the reference article linked separately.

environment

reference

PointCut formula

Specifier

The types of AspectJ pointcut designators supported by Spring AOP.

execution

for matching method execution join points, this is the primary pointcut designator you will use when working with Spring AOP

Format

format


execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
Format section pattern Remarks
modifiers-pattern Modifier Omission
ret-type-pattern Return type
declaring-type-pattern Declaration type Omission
name-pattern Method name
param-pattern Parameter type
throws-pattern Exception type Omission

Example


@Around("execution(public String com.example.*..*ServiceImpl.find*(String,Long,Long) throws Exception)")
                   ^^^^^^ ^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^
                   |      |      |                           |    |                  |
                   |      |      |                           |    |                  +--- throws-pattern
                   |      |      |                           |    +--- param-pattern
                   |      |      |                           +--- name-pattern
                   |      |      +--- declaring-type-pattern
                   |      +--- ret-type-pattern
                   +--- modifiers-pattern

This condition matches the findOne method of the class below.

Example


package com.example.service.impl;

@Service
public class EvianServiceImpl implements EvianService {

  //...abridgement

  public String findOne(String title, Long id, Long price) throws Exception {
    //...abridgement
  }

}

modifiers-pattern

Specify the qualifier. public is optional. However, Spring AOP only supports public methods, so you don't really need to specify it explicitly.

Example_(Omitted description)


@Around("execution(String *..*ServiceImpl.find*(String,Long,Long) throws Exception)")

Due to the proxy-based nature of Spring’s AOP framework, calls within the target object are by definition not intercepted. For JDK proxies, only public interface method calls on the proxy can be intercepted. With CGLIB, public and protected method calls on the proxy will be intercepted, and even package-visible methods if necessary. However, common interactions through proxies should always be designed through public signatures.

ret-type-pattern

Specifies the return pattern. If you do not need to specify the type, you can write it with "*".

Example_(Return value*Described in)


@Around("execution(* *..*ServiceImpl.find*(String,Long,Long) throws Exception)")

declaring-type-pattern

Specify the package name and class name pattern. It can be specified by partial match as described. It can be omitted.

Example_(Omitted description)


@Around("execution(public String find*(..) throws Exception)")

name-pattern

Specify the method name pattern. As mentioned above, it can be specified by partial match.

Example_(Describe the method name with a partial match)


find*(..)

Of course, you can also write without omitting it.

Example_(Description not omitted)


findOne(..)

param-pattern

Specifies the parameter pattern. There are several ways to describe it, but you can write it as ".." unless you need to specify it.

Example


@Around("execution(* *..*ServiceImpl.find*(..) throws Exception)")

When specifying partially. If the first argument is a String and the second and subsequent types are arbitrary (no arguments are required).

Example


find*(String,..)

If the number of arguments is fixed but the type is not fixed, use wildcards.

Example


find*(*,*,*)

If no argument is taken.

Example


find*()

throws-pattern

Specifies the exception pattern. You can also specify by partial match of the name.

Example


@Around("execution(* *..*ServiceImpl.find*(..) throws *Exception)")

It can be omitted.

Example


@Around("execution(* *..*ServiceImpl.find*(..))")

within

limits matching to join points within certain types (simply the execution of a method declared within a matching type when using Spring AOP)

Applies to the methods of the class specified by FQCN.

OK


@Around("within(com.example.service.impl.WeatherServiceImpl)")

Applies to the methods of the class under the specified package.

OK


@Around("within(com.example.service.impl.*)")

Applies to the methods of the specified class.

OK


@Around("within(*..WeatherServiceImpl)")

You cannot specify the interface.

NG


@Around("within(com.example.service.WeatherService)")
public interface WeatherService {
  //...abridgement
}

binding

Within cannot be bound.

@​within

limits matching to join points within types that have the given annotation (the execution of methods declared in types with the given annotation when using Spring AOP)

'@within' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

Applies to the method of the class with the specified annotation.

OK


@Around("@within(com.example.annotation.AopWithin)")

Example


@AopWithin
@Service
public class WeatherServiceImpl implements WeatherService {
  //...abridgement
}

binding

You can bind annotations to advisors.

OK


@Around("@within(aopWithin)")
public Object w4(ProceedingJoinPoint pjp, AopWithin aopWithin) throws Throwable {
  //...abridgement
}

target

limits matching to join points (the execution of methods when using Spring AOP) where the target object (application object being proxied) is an instance of the given type

'target' is more commonly used in a binding form :- see the following section on advice for how to make the target object available in the advice body.

Applies to the methods of the specified interface or implementation class of the abstract class.

OK


@Around("target(com.example.service.AbstractService)")

binding

You can bind the interface to an advisor.

OK


@Around("target(service)")
public Object t2(ProceedingJoinPoint pjp, AbstractService service) throws Throwable {
  //...abridgement
}

Since the data source is also an interface, it can be applied to the data source methods as shown below.

Example


@Around("target(datasource)")
public Object b1(ProceedingJoinPoint pjp, DataSource datasource) throws Throwable {
  //...abridgement
}

@​target

limits matching to join points (the execution of methods when using Spring AOP) where the class of the executing object has an annotation of the given type

'@target' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

I'm not sure. I looked it up, but I didn't understand.

args

'args' is more commonly used in a binding form :- see the following section on advice for how to make the method arguments available in the advice body.

Applies to methods that take the specified arguments. If you set args alone, a runtime error will occur, so we are narrowing down the target together with execution.

In this example, it is applied to a method that takes a class called WeatherForm as an argument.

OK


@Around("execution(* com.example.*..*.*(..)) && args(com.example.form.WeatherForm)")

The sequence of arguments specified for args is important. If you want to take an argument other than WeatherForm, you need to specify the argument or add "..".

Example


@Around("execution(* com.example.*..*.*(..)) && args(com.example.form.WeatherForm,..)")

binding

You can bind the arguments to the advisor.

OK


@Around("execution(* com.example.*..*.*(..)) && args(form,..)")
public Object a2(ProceedingJoinPoint pjp, WeatherForm form) throws Throwable {
  //...abridgement
}

@​args

'@args' can also be used in a binding form :- see the following section on advice for how to make the annotation object(s) available in the advice body.

Applies to methods that take an object of the class with the specified annotation as an argument.

OK


@Around("execution(* com.example.*..*.*(..)) && @args(com.example.annotation.AopTest)")

Example


@AopTest
public class WeatherForm implements Serializable {
  //...abridgement
}

It cannot be applied (it does not become effective) by the method of specifying annotation in the argument of the method as shown below.

NG


public void forecast(@AopTest WeatherForm form) {
  //...abridgement
}

binding

You can bind annotations to advisors.

OK


@Around("execution(* com.example.*..*.*(..)) && @args(aopTest)")
public Object a4(ProceedingJoinPoint pjp, AopTest aopTest) throws Throwable {
  //...abridgement
}

bean

Specify by the name of the bean managed by the Spring container. You can use wildcards in the name. This example applies to a bean method ending in "ServiceImpl".

Example


@Around("bean(*ServiceImpl)")

@​annotation

'@annotation' can also be used in a binding form :- see the following section on advice for how to make the annotation object available in the advice body.

Applies to the method with the specified annotation.

OK


@Around("@annotation(com.example.annotation.AopTest)")

Example


@AopTest
public void beforeTransaction() {
  //...abridgement
}

binding

You can bind annotations to advisors.

OK


@Around("@annotation(aopTest)")
public Object a2(ProceedingJoinPoint pjp, AopTest aopTest) throws Throwable {
  //...abridgement
}

Unsupported pointcut specifier

As of September 2017

The full AspectJ pointcut language supports additional pointcut designators that are not supported in Spring. These are: call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withincode, cflow, cflowbelow, if, @this, and @withincode. Use of these pointcut designators in pointcut expressions interpreted by Spring AOP will result in an IllegalArgumentException being thrown.

Recommended Posts

How to write Spring AOP pointcut specifier
How to unit test Spring AOP
How to write Rails
About Spring AOP Pointcut
How to write dockerfile
How to write docker-compose
How to write Mockito
How to write migrationfile
Bit Tetris (how to write)
How to write java comments
[Refactoring] How to write routing
Great poor (how to write)
[Note] How to write Dockerfile/docker-compose.yml
Introduction to Spring Boot ② ~ AOP ~
How to write Rails validation
How to write Rails seed
[Ruby] How to write blocks
How to write Rails routing
How to use Lombok in Spring
Studying Java # 6 (How to write blocks)
How to use Spring Data JDBC
[Rails] How to write in Japanese
[How to install Spring Data Jpa]
How to set Spring Boot + PostgreSQL
Baseball ball count (how to write)
How to write a ternary operator
Rails on Tiles (how to write)
[Rails] How to write exception handling?
How to write Java variable declaration
How to use ModelMapper (Spring boot)
Y-shaped road tour (how to write)
[RSpec] How to write test code
[Basic] How to write a Dockerfile Self-learning ②
How to include Spring Tool in Eclipse 4.6.3?
Summary of how to write annotation arguments
[Introduction to Java] How to write a Java program
[Java] How to output and write files!
To write Response data directly in Spring
[Spring MVC] How to pass path variables
How to write an RSpec controller test
How to split Spring Boot message file
[SpringBoot] How to write a controller test
How to write and explain Dockerfile, docker-compose
JDBC promises and examples of how to write
Rails: How to write a rake task nicely
[JavaFX] How to write Eclipse permissions in build.gradle
[Rails] How to write when making a subquery
How to use MyBatis2 (iBatis) with Spring Boot 1.4 (Spring 4)
How to write an if statement to improve readability-java
Understand how to share Spring DB connection (DB transaction)
How to make Spring Boot Docker Image smaller
About Spring AOP
JUnit 5: How to write test cases in enum
How to use Spring Boot session attributes (@SessionAttributes)
About spring AOP
Offline real-time how to write F06 implementation example
How to write code that thinks object-oriented Ruby
How to write test code with Basic authentication
How to bind to property file in Spring Boot
How to write React Native bridge ~ Android version ~
How to define multiple orm.xml in Spring4, JPA2.1