@Pointcut syntax detailed explanation
Table of contents
@Pointcut syntax detailed explanation
definition
Expression tags
execution
execution format:
example:
Wildcards matching AspectJ type:
within and @within
this
@target
@annotation
args and @args
Naming and anonymous entry point
Point-cut usage example:
Notification parameters
AOP Example
definition
Format: @ annotation(value= "Expression tag (expression format)")
like:@Pointcut (value=“execution(* .*(…))”)
Expression tags
- execution(): The connection point used to match the execution of the method
- args(): The execution method is used to match the parameters passed in the currently executed method as the specified type
- this(): Execution method used to match the current AOP proxy object type; note that the type matching of the AOP proxy object, which may include introducing interfaces and type matching;
- target(): Execution method used to match the current target object type; note that the type matching of the target object is the type matching, so that the introduction of the interface is also type matching;
- within(): Used to match method execution within a specified type;
- @args(): The execution of the specified annotation is held in the parameters passed in the method that matches the currently executed method;
- @target(): Execution method used to match the current target object type, where the target object holds the specified annotation;
- @within(): used to match so hold methods within the specified annotation type;
- @annotation: used to match the method that currently executes the method holds the specified annotation;
Among them, execution is the most commonly used.
execution
execution format:
execution(
modifier-pattern?
ret-type-pattern
declaring-type-pattern?
name-pattern(param-pattern)
throws-pattern?
)
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? name-pattern(param-pattern)throws-pattern?)
Among them ?Numbermodifiers-pattern?,declaring-type-pattern?,hrows-pattern?Yes optional
ret-type-pattern,name-pattern, parameters-patternIt is a must-have;
- modifier-pattern? Modifier matching, such aspublic Indicates matching public methods
- ret-type-patternReturn value matching,* Indicates any return value, class name of the full path, etc.
- declaring-type-pattern?Classpath matching
- name-pattern Method name matching,* Represent all,set*, representssetAll methods at the beginning
- (param-pattern) Parameter matching, specify method parameters (declared type),
(..) represents all parameters,
() represents a parameter,
(,String) means that the first parameter is any value and the second is of type String.
- throws-pattern? Exception type matching
example:
- execution(public * *(..)) Defines the execution of any public method
- execution(* set*(..)) Defines the execution of any method starting with "set"
- execution(* .*(..)) Defines the execution of any method of the AccountService interface
- execution(* .*.*(..)) defines the execution of any method in the service package
- execution(* ..*.*(..)) defines the execution of any method of any class in the service package and all subpackages
- execution(* …JoinPointObjP2.*(…)) Defines the execution of any method of JoinPointObjP2 class in the pointcutexp package and all subpackages:
Note: The closest (..) is the method name, and the closest (..)) is the class name or interface name, as in the example above JoinPointObjP2.∗(..))
Wildcards matching AspectJ type:
- *Match any number of characters;
- . .Match any repetition of a number of characters, such as matching any quantity subpacket in type pattern; and matching any quantity parameters in method parameter pattern.
- +: Matches the subtype of the specified type; it can only be placed after the type pattern as a suffix.
like:
- matchStringtype;
- java.*.String matchjavaAny "first-level subpackage" packagedStringType; if matched, but not match
- java..*matchjavaany type under package and any subpackage; if matched、
- .*ingMatch anyThe packagedingThe type of ending;
- + matchAnything under the packageNumberself-type; if matched, also match
within and @within
- within(.*) pointcutexpAny class in the package.
- within(…*) pointcutexpAny class in the package and all subpackages.
- @within() With@TransactionalAny method of all classes marked.
this
- this() ImplementedIntfAll classes of the interface, ifIntfNot an interface, limiting Intf single class.
When a class that implements an interface is AOP, the getBean method must cast as the interface type, and cannot be the type of the class.
@target
- @target() With@TransactionalAny method of all classes marked.
@annotation
- @annotation() With@TransactionalAny method of labeling.
@within and @target are annotations for classes, @annotation is annotations for methods
args and @args
- @args() Parameters with @TransactionalMethod of labeling.
- args(String) The parameters areStringA method of type (run is the decision).
Naming and anonymous entry point
When defining Pointcut, you can also use the &&, ∣∣, and ! operators
@Pointcut("execution(* .*(..)) && args(param)")
public void log(){
}
@Before("log(String param)")
public void beforeLog(){
//todo something...
}
//Equivalent to
@Before("execution(* .*(..)) && args(param)")
public void beforeLog(){
//todo something...
}
Another example:
@Pointcut("execution(* .*(..))")
private void logSender(){}
@Pointcut("execution(* .*(..))")
private void logReceiver(){}
@Pointcut("logSender() || logReceiver()")
private void logMessage(){}
In this example,logMessage()Will match anyMessageSenderandMessageReceiverAny method in
Point-cut usage example:
- one,execution:use"execution(Method Expression)” match method execution;
Example | describe | |
public * *(..) | Execution of any public method | |
* ..IPointcutService.*() | Any unparametered method in the IPointcutService interface under the package and all subpackages | |
* ..*.*(..) | Any method of any class under package and all subpackages | |
* ..IPointcutService.*(*) | Any method of the IPointcutService interface under the package and all subpackages has only one parameter | |
* (!..IPointcutService+) .*(..) | Any method that is not "IPointcutService interface and subtypes under packages and all subpackages" | |
* ..IPointcutService+.*() | Any unargumented method of the IPointcutService interface and subtype under packages and all subpackages | |
* ..IPointcut*.test*() | There is only one parameter type method with test starting with test under the package and all subpackages. Note that the match is matched based on the parameter type signed by the method, rather than determined based on the parameter type passed in during execution. For example, the method is defined: public void test(Object obj); even if it is passed in during execution, it will not match; | |
* ..IPointcut*.test*(..) throws IllegalArgumentException, ArrayIndexOutOfBoundsException, |
Any method of the IPointcut prefix type under package and all subpackages, and throws IllegalArgumentException and ArrayIndexOutOfBoundsException exceptions | |
* (..IPointcutService+&& +).*(..) | Any method that implements the IPointcutService interface and interface types under packages and all subpackages | |
@ * *(..) | Any method to hold @ annotations | |
@ @..Secure* *(..) | Any method that holds @ and @...Secure annotations | |
@( | ..Secure) **(..) | |
(@..Secure*) *(..) | Methods where any return value type holds @...Secure | |
*(@..Secure*).*(..) | Any method that defines a method that holds @...Secure | |
**(@..Secure(*) ,@..Secure(*)) | Any method with two parameters in signatures, and both parameters are marked by @Secure, such as public void test(@Secure String str1, @Secure String str1); | |
**((@ ..Secure *)) or **(@ ..Secure*) |
|
|
For example, public void test(Model model); and the Model class holds the @Secure annotation | ||
* *(@…Secure (@…Secure *) ,@ …Secure (@…Secure *)) | Any method with two parameters, and both parameters are marked by @ …Secure; and both parameters hold @ …Secure on their types; | |
* *(<…Model, …Model>, …) | Any method with one parameter, and the parameter type is a generic parameter with < …Model, …Model >; note that only the first parameter is matched, and the subtype is not included; for example, public void test(HashMap<Model, Model> map, String str); will not match, and "* *(<…Model,…Model>, …)" must be used for matching; and public void test(Map map, int i); will not match, because the generic parameters do not match | |
* *(<@…Secure *>) | Any method with a parameter (type) and the parameter type has a generic parameter, which holds the @...Secure annotation on the generic parameter type; such as public void test(Collection collection); Model type holds the @...Secure | |
* *(<? extends HashMap>) | Any method with one parameter and the passed parameter type has a generic parameter, which inherits from HashMap; Spring AOP tests currently do not work properly | |
* *(<? super HashMap>) | Any method with one parameter, and the passed parameter type has a generic parameter, which is the base type of HashMap; such as public voi test(Map map); Spring AOP test does not work normally at present | |
* (<@…Secure *>) | Any method with a parameter, and the parameter type has a generic parameter, which holds the @...Secure annotation; Spring AOP currently does not work properly |
- two,within:use"within(Type Expression)” matches the method execution within the specified type;
Example | describe |
within(..*) | Any method performed under packages and subpackages |
within(..IPointcutService+) | Any method of IPointcutService type and subtype under package or all subpackages |
within(@..Secure *) | Any method of any type that holds the...Secure annotation must be declared on the target object, and the declared on the interface does not work for it |
- 3. This: Use "this (full-qualified name of type)" to match the execution method of the current AOP proxy object type; note that the type matching of the AOP proxy object, which may include the introduction of interface methods and can also match; note that the expressions used in this must be fully qualified name of type and do not support wildcard characters;
Example | describe |
this(.. IPointcutService) |
The current AOP object implements any method of the IPointcutService interface |
this(.. IIntroductionService) |
The current AOP object implements any method of the IItroductionService interface |
- 4. target: Use "target (full-qualified name of type)" to match the execution method of the current target object type; note that the type matching of the target object is the type matching, which does not include the introduction of the interface and type matching; note that the expressions used in target must be fully qualified name of type and do not support wildcards;
Example | describe |
target(.chapter6. ) |
The current target object (non-AOP object) implements any method of the IPointcutService interface |
target(. ) |
Current target object (non-AOP object) Any method that implements the IItrainService interface cannot be introduced. |
- five,args:use"args(Parameter type list)" The parameters passed in matching the currently executed method are the execution method of the specified type; note that it matches the parameter type passed in, not the parameter type matching the method signature; the parameters in the parameter type list must be fully qualified name of the type, and wildcard characters do not support it; args is a dynamic entry point, and this entry point is very expensive, and it is best not to use it in non-special cases;
Example | describe |
args (,…) | Any method that starts with a method that accepts "incoming parameter type" and can be followed by any parameter of any type. The parameter type specified by args is dynamically matched at runtime. |
- six,@within: Use "@within(annotation type)" to match so that the method within the specified annotation type is held; the annotation type must also be a fully qualified type name;
Example | describe |
@within(.) | A class method in which the type corresponding to any target object holds Secure annotations; |
- seven,@target:use"@target(Annotation type)” matches the execution method of the current target object type, where the target object holds the specified annotation; the annotation type must also be a fully qualified type name;
Example | describe |
@target (.) | Any class method that target object holds Secure annotation; this annotation must be declared on the target object, and the declared on the interface will not work for it. |
- 8. @args: Use "@args(annotation list)" to match the currently executed parameters that hold the execution of the specified annotation; the annotation type must also be a fully qualified type name;
Example | describe |
@args (.) | Any method that accepts only one parameter, and the parameters passed in during the method run hold annotations.; dynamic entry point, similar to the arg indicator; |
- Nine,@annotation:use"@annotation(Annotation type)” matches the method in which the current execution method holds the specified annotation; the annotation type must also be a fully qualified type name;
Example | describe |
@annotation(. ) |
The current execution method holds annotations. Will be matched |
- 10. bean: The execution method of matching Bean objects with a specific name using "bean (Bean id or name wildcard)"; Spring ASP extension has no corresponding concept in AspectJ;
Example | describe |
bean(*Service) | Match all beans ending with Service name (id or name) |
- eleven,reference pointcut:Indicates referring to other named entry points;
@Pointcut(value="bean(*Service)")
private void pointcut1(){
}
@Pointcut(value="@args().")
public referencePointcutTest(JoinPoint jp){
...
}
Notification parameters
- 1) JoinPoint: Provide access to the target object, proxy object, method parameters and other data of the currently notified method
- 2)ProceedingJoinPoint: used to surround notifications, use the process() method to execute the target method
- 3): Provides static parts of the connection point to access, such as the notification method signature, connection point type, etc.:
Use the following method to declare on the notification method, which must be in the first parameter, and then use()You can get the notification method parameters
@Before(value="execution(* sayBefore(*))")
public void before(JoinPoint jp) {}
@Before(value="execution(* sayBefore(*))")
public void before( jp) {}
Automatic acquisition: Through point-cut expressions, the corresponding parameters can be automatically passed to the notification method, such as how the return value and exception mentioned in the previous chapter are passed to the notification method.
existSpring AOPIn addition toexecutionandbeanThe indicator cannot pass parameters to the notification method, and other indicators can automatically pass the corresponding matching parameters or objects to the notification method.
@Before(value="execution(* test(*)) && args(param)", argNames="param")
public void before1(String param) {
("===param:" + param);
}
Point-cut expressionexecution(* test()) && args(param) :
1) Firstexecution( test(*))Match any method nametest, and there is a parameter of any type;
2)args(param)The parameter with the same name on the notification method will be first searched, and the parameter passed in is matched when the method is executed (runtime) is used to use the parameter type of the same name, i.e.; If matched, the notified parameter will be passed to the parameter with the same name on the notification method.
Other indicators (exceptexecutionandbeanIndicators) can be used in this way for parameter binding.
There is a problem here, that is, the aforementioned similar to [3.1.2 Constructor InjectionParameter name injection restrictions in 】: If the variable debugging information is not generated in the class file, the method parameter name cannot be obtained.
So we can use the policy to determine the parameter name:
If we specify the parameter name through the "argNames" attribute, then we need to specify it;
@Before(value=" args(param)", argNames="param") //It is clearly specified
public void before1(String param) {
("===param:" + param);
}
If the first parameter type is JoinPoint, ProceedingJoinPoint or type, the parameter name should be omitted from the "argNames" property (optional, also correct to write). These type objects will be automatically passed in, but must be used as the first parameter;
@Before(value=" args(param)", argNames="param") //It is clearly specified
public void before1(JoinPoint jp, String param) {
("===param:" + param);
}
if"classThe file contains variable debug information" will use the parameter names in these method signatures to determine the parameter names;
@Before(value=" args(param)") //ArgNames is not needed
public void before1(JoinPoint jp, String param) {
("===param:" + param);
}
If there is noclassThe file contains variable debugging information", and will try your own parameter matching algorithm. If you find that the parameter binding is ambiguity, it will be thrownAmbiguousBindingExceptionException; For point-cut expressions with only one binding variable, and the notification method only accepts one parameter, indicating that the binding parameters are clear, so that the pairing can be successfully paired.
@Before(value=" args(param)")
public void before1(JoinPoint jp, String param) {
("===param:" + param);
}
The above strategy will be thrownIllegalArgumentException。
Next, let's illustrate the combination situation:
@Before(args(param) && target(bean) && @annotation(secure)",
argNames="jp,param,bean,secure")
public void before5(JoinPoint jp, String param,
IPointcutService pointcutService, Secure secure) {
……
}
You can also automatically obtain parameters using named entry points:
@Pointcut(value="args(param)", argNames="param")
private void pointcut1(String param){}
@Pointcut(value="@annotation(secure)", argNames="secure")
private void pointcut2(Secure secure){}
@Before(value = "pointcut1(param) && pointcut2(secure)", argNames="param, secure")
public void before6(JoinPoint jp, String param, Secure secure) {
……
}
AOP Example
@Aspect
@Component
public class NotVeryUsefulAspect {
@AfterReturning(value="execution(* .*(..))")
private void logReceiver(){
("Enter entry point logReceiver...");
}
@Pointcut(value="execution(* .*(..)) && args(param)")
private void pointcut(String param){
("Pointcut()"+param);
}
//The method body will not be executed
@Pointcut("within(.*)")
public String inWebLayer() {
("enter point inWebLayer()");
return "Return value loading";
}
@Before(value="inWebLayer()")
private void beforeinWebLayer(){
("beforeinWebLayer~~");
}
@Before(value="pointcut(param)")
private void beforePointcut(String param){
("beforePointcut:"+param);
}
@AfterReturning(pointcut="inWebLayer()",returning="retVal")
public void doAccessCheck(Object retVal) {
("doAccessCheck:"+retVal);
}
@Around(value="execution(* .*(..))")
private Object aroundLayer(ProceedingJoinPoint pjp) throws Throwable{
// start stopwatch
Object retVal = ();
// stop stopwatch
("aroundLayer~~");
return returnVal;
}
}
Reference from:
/
/xiaoyiaoyou/article/details/45972363