preface
This article deals with AspectJ in an AOP programming style. Need to understand the relevant knowledge of annotations juejin.cn/post/692232…
www.iteye.com/blog/jinnia…
Introduction to the
AspectJ weaves the code statically, that is, injecting it at compile time. AspectJ is an AOP technique in the strictest sense because it provides complete annotations for faceted programming, allowing the user to weave code without caring about the principles of bytecode, since the faceted code written is the actual code to weave into. AspectJ is based on aspects, a new modularity mechanism for describing crosscutting concerns scattered across objects, classes, or functions.
concept
- Aspect: a modularization of a concern that may crosscut multiple objects.
- Join Point: a Point in a program that can be accessed, such as when a method is called or when a variable is read.
- Pointcut: a Pointcut where code is injected, which is essentially a conditional Join Point, such as only injecting code into a particular method.
- Advice: Advice. Code injected at a pointcut is typically of the before, after, and around types.
- Target Object: The Target Object that is crosscut by one or more aspects to intercept operations.
- Weaving: The process of Weaving Advice code into target objects.
- Inter-type declarations: Declarations of additional methods or attributes for a type.
Usage scenarios
The actual common scenarios for AspectJ are roughly as follows
- Statistics buried point
- Log printing/logging
- Data validation
- Behavior to intercept
- Performance monitoring
- Dynamic permission control
use
- Use AspectJ’s language for development
- Developed in the Java language with annotations provided by AspectJ
AspectJ is typically used as an annotation on Android Studio. Since Android Studio does not have the AspectJ plug-in, it cannot recognize the syntax of AspectJ, so it is used as an annotation
The basic grammar
Join Point
Join points represent Join points, or points that AOP can weave into code
Join Point | instructions |
---|---|
Method call | Method called |
Method execution | Methods to perform |
Constructor call | The constructor is called |
Constructor execution | Constructor execution |
Field get | Reads the properties |
Field set | Write attributes |
Static initialization | Static block initialization |
Handler | Exception handling |
Advice execution | All Advice implemented |
Pointcuts
Pointcuts are specific Pointcuts that determine exactly where to weave code
Join Point | Pointcuts syntax |
---|---|
Method call | call(MethodPattern) |
Method execution | execution(MethodPattern) |
Constructor call | call(ConstructorPattern) |
Constructor execution | execution(ConstructorPattern) |
Field get | get(FieldPattern) |
Field set | set(FieldPattern) |
Pre-initialization | initialization(ConstructorPattern) |
Initialization | preinitialization(ConstructorPattern) |
Static initialization | staticinitialization(TypePattern) |
Handler | handler(TypePattern) |
Advice execution | adviceexcution() |
Pointcuts have other methods to select a Join Point:
Pointcuts synatx | instructions |
---|---|
within(TypePattern) | Join points in TypePattern compliant code |
withincode(MethodPattern) | Join Point in some methods |
withincode(ConstructorPattern) | Join points in some constructors |
cflow(Pointcut) | Pointcut selects all Join points in the control flow of Pointcut P, including P itself |
cflowbelow(Pointcut) | Pointcut selects all Join points in the control flow of Pointcut P, excluding P itself |
this(Type or Id) | Whether the this object to which the Join Point belongs is instanceOf Type or the Type of Id |
Target (Type or Id) The object on which the Join Point is located (for example, the object to which the Call or execution operator applies) | Whether instanceOf Type or Id Type |
args(Type or Id, …) | The type of a method or constructor parameter |
if(BooleanExpression) | ThisJoinPoint can only use static attributes, Pointcuts or Advice exposed arguments, and thisJoinPoint objects |
Pointcut expressions are ok! Combination,, &&, | |! Pointcut0 &&pointcut1 Pointcut0 &&pointcut1 Pointcut0 &&pointcut1 Pointcut0 &&pointcut1 Pointcut0 Pointcut0 | | Pointcut1 choose accord with Pointcut0 or Pointcut1 Join Point.
The syntax of Pointcuts involves some patterns. Here are the rules for these patterns
Pattern | The rules |
---|---|
MethodPattern | [!] [@annotation] [public,protected,private] [static] [final] Return value type [class name.] Method name (parameter type list) [throws exception type] |
ConstructorPattern | [!] [@annotation] [public,protected,private] [final] [Class name.]new(parameter type list) [throws exception type] |
FieldPattern | [!] [@annotation] [public,protected,private] [static] [final] Property type [class name.] Property name |
TypePattern The same applies to other types of Pattern, using ‘! ‘, ‘, ‘… ‘, ‘+’, ‘! ‘matches all strings except. ‘*’ uses things alone to match any type, ‘.. ‘Matches any string, ‘.. ‘used alone to match any type of any length, ‘+’ to match itself and its subclasses, and ‘… ‘is an indefinite number |
Grammar website www.eclipse.org/aspectj/doc…
Commonly used Pointcut examples
-
execution(void void android.view.View.OnClickListener+.onClick(..) ) — when the onClick method of OnClickListener and its subclasses executes
-
call(@retrofit2.http.GET public * com.johnny.core.http.. * (..) ) — all GET methods under the package starting with ‘com.johnny.core. HTTP ‘are called
-
call(android.support.v4.app.Fragment+.new(..) ) — constructor call for Fragment and its subclasses in the support package
-
Set (@inject * *) — writes all @inject annotated properties
-
handler(IOException) && within(com.johnny.core.http..) — IOException handled in package code beginning with ‘com.johnny.core. HTTP
-
execution(void setUserVisibleHint(..) ) && target (android. Support. The v4. App. Fragments) && args (Boolean) – perform setUserVisibleHint fragments and its subclasses (Boolean) method
-
execution(void Foo.foo(..) ) && cflowbelow(execution(void Foo.foo(..) )) — recursively executing foo.foo () after executing foo.foo ()
Pointcut declarations
Pointcuts can be in the ordinary course of the class or the Aspect in the class definition, by the org. Aspectj. Lang. The annotation. Pointcut annotations modified method declaration, is only a void method return values. @pointcut modified methods can only be implemented by empty methods and cannot have throws statements. The parameters of the method correspond to those of the Pointcut.
@Aspect class Test { @Pointcut("execution(void Foo.foo(..) ") public void executFoo() {} @Pointcut("executFoo() && cflowbelow(executFoo()) && target(foo) && args(i)") public void loopExecutFoo(Foo foo, int i) {} }Copy the code
Advice
Advice is code woven into a pointcut, and there are five types in AspectJ: Before, After, AfterReturning, AfterThrowing, and Around.
Advice | instructions |
---|---|
@Before | Before executing Join Point |
@After | Normal return and throw exceptions are included after the Join Point |
@AfterReturning | If Join Point is a method call and return is normal, all types are matched if no return type is specified |
@AfterThrowing | When a Join Point is a method call and an exception is thrown, all types are matched if no exception type is specified |
@Around | Replace the Join Point code, if you want to perform the original code, to use ProceedingJoinPoint. Proceed () |
Fter and Before do not return a value, but Around is intended to replace the original Join Point, so it will generally return a value, and the type of return value needs to match the code of the selected Join Point. It cannot be used with other Advice and will not be valid if you declare Before or After After a Pointcut Around.
Advice must be public, and the return value of Before, After, AfterReturning, and AfterThrowing must be void. Advice to use JoinPoint, JoinPointStaticPart, JoinPoint. EnclosingStaticPart, in a method statement for additional parameters, The @around method can use ProceedingJoinPoint, which calls the Proceed () method.
Aspect
Aspect is the key unit in AOP, the Aspect, and we typically put the related Pointcut and Advice in an Aspect class, In AspectJ-based annotation development, you simply add the @aspect annotation to the class header; @Aspect does not modify the interface. Specific use can try, according to a set of their own juejin.cn/post/684490…