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
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
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
}
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
}
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)")
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,..)")
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
}
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
}
You can bind annotations to advisors.
OK
@Around("@annotation(aopTest)")
public Object a2(ProceedingJoinPoint pjp, AopTest aopTest) throws Throwable {
//...abridgement
}
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