Advice
In addition to receiving JoinPoint
(non-Around Advice) or ProceedingJoinPoint
(Around Advice) external parameters
You can also directly receive a pointcut related to an object method for performing
such as
- Entry point method parameters
- The starting point of the target object
target
( )- Entry point proxy object
this
( )- Wait.
Article Directory
# Obtain entry point method parameters
## designated [class - Method - Parameter]
Suppose we now have an id userService
of bean
defines a findById(int id)
method
We want to define a Advice
to intercept this method, and the findById()
parameters as the Advice
parameter processing method
I.e., each call to the findById () passed parameters are passed to the Advice processing method
So this way we can define as follows.
@Before(value="bean(userService) && execution(* findById(java.lang.Integer)) && args(id)", argNames="id")
public void beforeWithParam( JoinPoint joinPoint , Integer id ) {
System.out.println(this.getClass().getName()+" ID is : " + id);
}
This definition is very accurate above definition
Through the expression " bean(userService) && execution(* findById(java.lang.Integer))
" has beenWe need to explicitly specify the interception ofIt is id
or name
was userService的findById(Integer)
amethod
Behind the addition of another args(id)
is doing with it?
-
Its role now
findById(Integer)
is similar
to express our itsThe method must receive only a pointcut parameter, And this is the parameter type currently defined and theAdvice
parameters of the processing methodid
of the same type, in the example of the above it is actually requiredInteger
type; -
In addition it has a very important role, this designation by the corresponding
Advice
processWhen performing the method corresponding to the received parameter value entry point method。
In the example above, the author specifically to the
Advice
processing method of adding aJoinPoint
parameter for purposes of illustrationJoinPoint
,ProceedingJoinPoint
parameters can be defined directly in theAdvice
methodThe first argumentAnd it can beCoexist with other parameters receivedof.
## designated [class - Parameter]
In fact, if we do not just need to intercept findById(Integer)
method, but need to intercept id
as userService
of bean
theallReceiving a int/Integer
parameter of the method, we can simplify the configuration of the above in the following manner.
@Before(value="bean(userService) && args(id)", argNames="id")
public void beforeWithParam2(int id) {
System.out.println(this.getClass().getName()+" ID is : " + id);
}
## designated [class - (part of) parameters]
If we need to intercept method may have multiple parameters, but weFocus only on the first argumentThat we can adjust to expressions such as
The first argument is only concerned with int/Integer
the type, and Advice
receiving the corresponding processing method parameter method.
@Before(value="bean(userService) && args(id,..)", argNames="id")
public void beforeWithParam2(int id) {
System.out.println(this.getClass().getName()+" ID is : " + id);
}
## argNames parameters
We can see in the above example we specify @Before
the argNames
value of the property id
, then this argNames
property has what effect?
argNames
Property is forSpecified in the expression parameter names and Advice application method parameter is how the correspondingargNames
Specified in the parameter name must be consistent with the expression andAdvice
inconsistent method parameter names;- When a plurality of parameters used in the expression,
argNames
the need to specify a plurality of parameters,Multiple parameters are separated by commas - These parameters must order the corresponding
Advice
definition of the methodParameter order is consistent with。
Example, the following example
@Before(value="bean(userService) && args(name, sex)", argNames="sex, name")
public void beforeWithParam3(int sex1, String name1) {
System.out.println("sex is : " + sex1);
System.out.println("name is : " + name1);
}
- We
Pointcut
used the expressionname
andsex
two parameters
of ourAdvice
approach takes two parameters, respectively,sex1
andname1
- We want
Pointcut
expressionname
parameter corresponding to theAdvice
second parameter processing methods, i.e.,name1
desiredPointcut
expressionsex
parameter corresponding toAdvice
the first parameter processing method, i.e.,sex1
Then
- We specify
@Before
annotationsargNames
must be defined when the parametersname
andsex
parameters andAdvice
the relationship between the method of processing parameters - AndSequence consistent with the requirement parameter corresponding to the order processing method
That which argument is the need toAdvice
put the parameters which put the first argument matching processing method of the first
and the second parameter matching the second place
(in our example this should besex
put first,name
put second.)
If the expression which uses a plurality of parameters, these parameters may be in the order of expression and Advice
methods corresponding to the order of the parameters are inconsistent,
## argNames can be omitted
@Before
Annotated argNames
parameter is not required, it is only free in our compiled bytecode DEBUG
information or Pointcut
parameter names used in the expression Advice
parameter names inconsistent treatment when needed.
So included in the bytecode compilation of DEBUG
information and Advice
the parameter name and Pointcut
when the same parameter names used in the expression, we can put the argNames
argument is omitted.
@Before(value="bean(userService) && args(id)")
public void beforeWithParam2(int id) {
System.out.println(this.getClass().getName()+" ID is : " + id);
}
Article Directory
# Obtain this target
this
The object is Spring
generated bean
in the proxy object.
The example below is Advice
a method of receiving this
the object
We give Advice
way to specify aNeed to intercept the this
object typeParameters
Is then used in an expression this
expression defining the type
Expression corresponding to the defined type as Advice
method parameter.
@Before("this(userService)")
public void beforeWithParam4(IUserService userService) {
//this对象应该是一个代理对象
System.out.println(this.getClass().getName()+"==============传递this对象: " + userService.getClass());
}
# Mixed use
Our Advice
method can simultaneously receive a plurality of parameters of the target method, it can also be received at the same time this
other objects, i.e., they can be used mixed.
The following example we simultaneously receives this
and target method int/Interger
type parameter.
@Before("this(userService) && args(id)")
public void beforeWithParam5(IUserService userService, int id) {
System.out.println(this.getClass().getName()+"===========" + id + "==============" + userService.getClass());
}
# Gets the target object
Gets target
the object is also relatively simple, just need to change the expression target
type of expression can be.
@Before("target(userService)")
public void beforeWithParam6(IUserService userService) {
System.out.println(this.getClass().getName()+"==============传递target对象: " + userService.getClass());
}
- Otherwise, the general
Object target = ProceedingJoinPoint.getTarget();
acquisitiontarget
target
Andthis
not necessarily the same (JDK implementation - the same; CGLIB achieve - different)
"AOP principle - - inherited objects (JDK) / composite object (CGLIB), AspectJ-ProceedingJoinPoint- getSignature details and the details of this potential bug"
# Get the annotation object
When our Pointcut
time is through annotation expression type matching, we can also in Advice
acquiring annotation object matching processing method
As described in this example, such as the use of other @target
like are similar.
@Before("@annotation(annotation)")
public void beforeWithParam7(MyAnnotation annotation) {
System.out.println(this.getClass().getName()+"==============传递标注在方法上的annotation: " + annotation.annotationType().getName());
}
@Pointcut("@annotation(com.edut.springboot.tarena.common.annotation.RequiredCache)")
This is to identify the correspondingannotation
tangent point
# Generic parameters
Sometimes our Advice
method needs to receive an entry pointMethod parametersDefinedNot a specific type, but a generic, How to do in this situation?
You might be thinking that I'll corresponding
Advice
method parameter is defined asObject
the type of good, anyway, all types can be converted toObject
type.
Right, this is not wrong,butHe says you can not put if you just want to intercept certain specific types of parameters to callAdvice
the method parameter type is defined asObject
, and this had to be judged in the method body inside
We candirectThe Advice
method parameter type is defined as a method parameter type we want to block.
For example, we have used the following definition of such a generic way, we only want to call the testParam
parameter type transfer method is Integer
to intercept only type.
public <T> void testParam(T param);
-
That this time we can put our
Advice
expression defined as such, the former receives precisely defined method calledtestParam
, return typevoid
, which is precisely defined as a method parameterInteger
type parameter
is actually the former can also be defined as "execution(void testParam(Integer))
." -
You might want to see this
Why not just an expression is defined as "execution(void testParam(param))
" mean?
Asexecution
isnot supportAdvice
Method parameter bindingBasically supportsAdvice
parameter binding onlythis
,target
,args
and a corresponding increase in the form of notes@annotation
.
@Before("execution(void testParam(..)) && args(param)")
public void beforeWithParam8(Integer param) {
System.out.println("pointcut expression[args(param)]--------------param:" + param);
}
These are the parameters passed to the way conventional processing method Advice
Some examples may not be talked about, such as @target this, these are in fact similar.
We are all above include @Before this Advice is concerned, in fact, other parameters of Advice at the time of reception is also similar.
Reference Document
1, official documents
(Note: This article is written based on Spring4.1.0, wrote on Friday, January 20 2017)