Pointcut expression type
The expression types of pointcut of standard AspectJ Aop are very rich, but Spring Aop only supports 9 of them, and a total of 11 (10 + 1) types of expressions are extended by Spring Aop, as follows.
- Execution: it is generally used to specify the execution of methods. It is used most.
- within: Specifies the execution of all methods of some types. It can also be used to specify a package.
- This: Spring Aop is based on dynamic proxy, and the generated bean is also a proxy object. This is the proxy object. When this object can be converted to the specified type, the corresponding entry point is it, and Spring Aop will take effect.
- target: when the proxied object can be converted to the specified type, the corresponding entry point is it, and Spring Aop will take effect.
- args: takes effect when the parameter of the executed method is the specified type.
- @Target: takes effect when the specified annotation is on the target object of the proxy.
- @args: takes effect when there is a specified annotation on the parameter type of the executed method.
- @Within: similar to @ target, the official documents and the Internet say that @ within only needs the specified annotation on the target object's class or parent class, then @ within will take effect, while @ target must have the specified annotation on the target object's class. According to the author's test, both are as long as there are specified annotations on the target class or parent class.
- @Annotation: takes effect when there is a specified annotation on the executed method.
- reference pointcut: (often used) refers to referencing other named pointcuts. Only @ ApectJ style is supported, but Schema style is not
- Bean: takes effect when the method called is the method of the specified bean. (supported by Spring AOP extension)
Pointcut When defining, you can also use&&,||,! These three operations. Perform logical operations. Various conditions can be combined
The pointcut indicators supported by AspectJ pointcuts include: call, get, set, preinitialization, staticinitialization, initialization, handler, adviceexecution, withCode, cflow, cflowbelow, if, @ this, @ withCode; However, Spring AOP does not support these indicators at present. Using these indicators will throw IllegalArgumentException. These indicators may be extended later by Spring AOP
All pointcut expression types supported by aspectj are as follows (but Spring currently only supports the above)
See org.aspectj.weaver.tools.PointcutPrimitive enumeration class:
// amount to AspectJ A total of 24 are provided (not included of course) Spring own bean (mode of) public final class PointcutPrimitive extends TypeSafeEnum { public static final PointcutPrimitive CALL = new PointcutPrimitive("call",1); public static final PointcutPrimitive EXECUTION = new PointcutPrimitive("execution",2); public static final PointcutPrimitive GET = new PointcutPrimitive("get",3); public static final PointcutPrimitive SET = new PointcutPrimitive("set",4); public static final PointcutPrimitive INITIALIZATION = new PointcutPrimitive("initialization",5); public static final PointcutPrimitive PRE_INITIALIZATION = new PointcutPrimitive("preinitialization",6); public static final PointcutPrimitive STATIC_INITIALIZATION = new PointcutPrimitive("staticinitialization",7); public static final PointcutPrimitive HANDLER = new PointcutPrimitive("handler",8); public static final PointcutPrimitive ADVICE_EXECUTION = new PointcutPrimitive("adviceexecution",9); public static final PointcutPrimitive WITHIN = new PointcutPrimitive("within",10); public static final PointcutPrimitive WITHIN_CODE = new PointcutPrimitive("withincode",11); public static final PointcutPrimitive CFLOW = new PointcutPrimitive("cflow",12); public static final PointcutPrimitive CFLOW_BELOW = new PointcutPrimitive("cflowbelow",13); public static final PointcutPrimitive IF = new PointcutPrimitive("if",14); public static final PointcutPrimitive THIS = new PointcutPrimitive("this",15); public static final PointcutPrimitive TARGET = new PointcutPrimitive("target",16); public static final PointcutPrimitive ARGS = new PointcutPrimitive("args",17); public static final PointcutPrimitive REFERENCE = new PointcutPrimitive("reference pointcut",18); public static final PointcutPrimitive AT_ANNOTATION = new PointcutPrimitive("@annotation",19); public static final PointcutPrimitive AT_THIS = new PointcutPrimitive("@this",20); public static final PointcutPrimitive AT_TARGET = new PointcutPrimitive("@target",21); public static final PointcutPrimitive AT_ARGS = new PointcutPrimitive("@args",22); public static final PointcutPrimitive AT_WITHIN = new PointcutPrimitive("@within",23); public static final PointcutPrimitive AT_WITHINCODE = new PointcutPrimitive("@withincode",24); private PointcutPrimitive(String name, int key) { super(name, key); } }
Use example
execution:
Execution is the most used Pointcut expression, which represents the execution of a method. Its standard syntax is as follows.
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern) throws-pattern?)
- Modifier pattern
- The RET type pattern can be * to indicate any return value, class name of the full path, etc
- Declaring type pattern
- Method name pattern can specify the method name or represent all methods, and set represents all methods starting with set
- Parameter matching ((param pattern)) can specify specific parameter types. Multiple parameters are separated by "," and each parameter can also be represented by "". For example, (String) represents the method of matching a String parameter; (, String) indicates a method matching two parameters. The first parameter can be of any type, and the second parameter is of String type; You can use (...) to represent zero or more arbitrary parameters
- Throws pattern
- Options are followed by "
Here are some examples:
//Indicates that all methods are matched 1)execution(* *(..)) //Indicates a match com.fsx.run.UserService All public methods in 2)execution(public * com.fsx.run.UserService.*(..)) //Indicates a match com.fsx.run All methods under the package and its sub packages 3)execution(* com.fsx.run..*.*(..))
When defining Pointcut, you can also use & &, |! These three operations. Perform logical operations
// Signature: message sending aspect @Pointcut("execution(* com.fsx.run.MessageSender.*(..))") private void logSender(){} // Signature: message receiving aspect @Pointcut("execution(* com.fsx.run.MessageReceiver.*(..))") private void logReceiver(){} // Only when the sending or receiving section is satisfied will it be cut in @Pointcut("logSender() || logReceiver()") private void logMessage(){}
In this example, logMessage() will match any method in any MessageSender and MessageReceiver.
When we have many aspects, we can put all aspects into a single class for unified management, such as the following:
//Centrally manage all pointcut expressions public class Pointcuts { @Pointcut("execution(* *Message(..))") public void logMessage(){} @Pointcut("execution(* *Attachment(..))") public void logAttachment(){} @Pointcut("execution(* *Service.*(..))") public void auth(){} }
In this way, the full class name + method name is used
@Before("com.fsx.run.Pointcuts.logMessage()") public void before(JoinPoint joinPoint) { System.out.println("Logging before " + joinPoint.getSignature().getName()); }
within:
within is used to specify the type, and all methods in the specified type will be intercepted.
// AService All external calling methods below will be intercepted. Note: only AService Subclasses will not be intercepted @Pointcut("within(com.fsx.run.service.AService)") public void pointCut() { }
Therefore, it should be noted here: the above is the AService interface, which can not achieve the interception effect. Only the implementation class can be written:
//Only implementation classes can be written here @Pointcut("within(com.fsx.run.service.impl.AServiceImpl)") public void pointCut() { }
Match all classes within the package and sub packages:
@Pointcut("within(com.fsx.run.service..*)") public void pointCut() { }
this:
Spring Aop is proxy based, and this represents a proxy object. The syntax of Pointcut expression of this type is this(type). When the generated proxy object can be converted to the type specified by type, it indicates a match. The proxy objects generated by JDK interface based proxy and CGLIB based proxy are different. (note the difference from within above)
// In this way, you can intercept it AService All external calling methods of all subclasses @Pointcut("this(com.fsx.run.service.AService*)") public void pointCut() { }
target:
Spring Aop is proxy based, and target represents the proxy target object. When the proxied target object can be converted to the specified type, it indicates a match. Note: different from the above, this is the target, so if you want to cut in, you can only write the implementation class
@Pointcut("target(com.fsx.run.service.impl.AServiceImpl)") public void pointCut() { }
args:
args is used to match method parameters.
- 1. 'args()' matches any method without parameters.
- 2. "args(java.lang.String)" matches any method that takes only one parameter, and the type of this parameter is String.
- 3. "args(...)" method with arbitrary parameters.
- 4. "args(java.lang.String,...)" matches a method with any parameter, but the type of the first parameter is String.
- 5. "args(..., java.lang.String)" matches the method with any parameter, but the type of the last parameter is String.
@Pointcut("args()") public void pointCut() { }
The scope of this match is very wide, so it is generally used in combination with other expressions
@target:
@Target matching when the type corresponding to the proxy target object and its parent type have the specified annotation.
//Can cut into class (non method) standards MyAnno Annotate all external call methods @Pointcut("@target(com.fsx.run.anno.MyAnno)") public void pointCut() { }
@args:
@args matches the case where the called method contains parameters and the corresponding parameter type has the specified annotation. For example:
// matching**Method parameter type**have MyAnno Annotated method call.
//If we have a method add(MyParam param) that receives a parameter of MyParam type, and the MyParam class has the annotation MyAnno, it can be matched by the Pointcut expression @Pointcut("@args(com.fsx.run.anno.MyAnno)") public void pointCut() { }
@within:
@within is used to match the case where the type corresponding to the target object being proxied or its parent type has the specified annotation, but only when calling the method on the class with the specified annotation.
"@ within(com.fsx.run.anno.MyAnno)" matches the MyAnno annotation on the class declared by the called method. For example, if the annotation MyAnno is used on a ClassA and a method a () is defined, the Pointcut will be matched when calling the ClassA.a() method; If there is a ClassB without MyAnno annotation, but it inherits from ClassA, and it defines a method b(), the Pointcut will not be matched when calling the ClassB().b() method, but the method call will be matched when calling ClassB().a(), because a () is defined on the parent type ClassA and MyAnno annotation is used on ClassA. However, if the subclass ClassB overrides the a() method of the parent class ClassA, the Pointcut does not match when calling the ClassB.a() method.
@annotation: it is also used more
@annotation is used to match cases where there are specified annotations on the method.
// Methods marked with this annotation on all methods can be matched @Pointcut("@annotation(com.fsx.run.anno.MyAnno)") public void pointCut() { }
We can also write in this way, which is very convenient to obtain the annotation on the method
@Before("@annotation(myAnno)") public void doBefore(JoinPoint joinPoint, MyAnno myAnno) { System.out.println(myAnno); //@com.fsx.run.anno.MyAnno() System.out.println("AOP Before Advice..."); }
reference pointcut: pointcut reference (used a lot)
@Aspect public class HelloAspect { @Pointcut("execution(* com.fsx.service.*.*(..)) ") public void point() { } // This is one`reference pointcut` Even so @Before("point1() && point2()") @Before("point()") public void before() { System.out.println("this is from HelloAspect#before..."); } }
bean: This is a method added by spring, which is unique to spring
Bean is used to match when the method of a specified Spring bean is called.
1. "bean(abc)" matches the method call of the bean with id or name abc in the Spring Bean container.
2. "bean(user *)" matches the method calls of all beans whose id or name starts with user.
// This will cut into AServiceImpl In the method of external call of class @Pointcut("bean(AServiceImpl)") public void pointCut() { }
Type matching syntax
*: matches any number of characters;
...: matches the repetition of any number of characters, such as any number of subpackages in the type pattern; Match any number of parameters in the method parameter pattern.
+: matches subtypes of the specified type; Can only be placed after the type mode as a suffix.
java.lang.String matching String Type; java.*.String matching java Under any "first level sub package" under the package String Type; Such as matching java.lang.String,But it doesn't match java.lang.ss.String java..* matching java Any type under the package and any sub package. Such as matching java.lang.String,java.lang.annotation.Annotation java.lang.*ing Match any java.lang Under the package ing Type of ending; java.lang.Number+ matching java.lang Any under the package Number Subtype of; Such as matching java.lang.Integer,Also match java.math.BigInteger
Combination of expressions
The combination of expressions is actually the logical operation of the corresponding expression, and, or and non. They can be used to group multiple expressions together.
1. "Bean (userService) & & args()" matches all parameterless methods of the bean with id or name userService.
2. "Bean (userService) | @ annotation (MyAnnotation)" matches the method call of the bean with id or name of userService, or the method call with MyAnnotation annotation on the method.
3. "Bean (userService) & &! Args()" matches all parameterized method calls of the bean with id or name userService.