[JAVA] List of point cuts for making finer point cuts

Introduction

The times may come? Aspect-oriented programming, what is the AspectJ language was summarized and described about pointcuts, but there were more pointcuts than I expected. It's long and difficult to understand, and there seems to be pointcuts implemented in AspectJ, so I decided to divide it. Please note that it was divided into dogmatism and prejudice.

Point cuts that could not be put together

** Pointcut related to static initializer **

Static initialization is provided for pointcuts related to static initializers Represents the "time" when a static initializer that takes a type pattern as an argument and initializes a static field in a class is called and executed.

Sample.java


//Write the class name directly or use wildcards
staticinitialization(Session+)

What is a static initializer?

Also known as a static initializer or class initializer. A special method declared for each class to initialize the value of a static field

staticInitializer.java


static {
  //Code that initializes the value of a static field
}

** Pointcuts related to where join points occur **

Pointcuts can be combined using operators However, be careful, as the call seems to wrap the execution as shown in the above figure, so call && exectuion and Even if it looks like the code below, it's actually different

Sample.java


class Sample {
  Sample() {
    Main.init()
  }
}

class Main {
  static void init() {
    hoge();
  }
  static int length() {
    return hoge
  }
}

As shown in the figure below, execution specifies the light blue part (the part outside the join point), and call is in the green part. && condition never becomes True

qiita8.PNG

But what if you want to create such a condition? In addition to selecting a specific type of join point for the solution, we also offer a primitive pointcut that selects the join point based on the location in the program.

: black_small_square: ** within (type pattern) ** Select all join points that occur in class or interface declarations that match the type pattern Any type of join point

: black_small_square: ** withincode (method pattern) ** or ** withincode (constructor pattern) ** Select all join points that occur in the body of the method or constructor that match the argument pattern Any type of join point

By using the above, you can specify that it is in a specific class or method.

qiita9.PNG

** Point cut related to business flow **

There are two pointcuts related to business flow, ** cflow ** and ** cflow below **. Take a pointcut as an argument to represent "time"

Sample.java


cflow(call(void Main.init()))

:black_small_square:cflow Selects all join points that occur between the start and end of the join point P selected by the argument pointcut. cflow selects the join point P selected by the argument pointcut

:black_small_square:cflowbelow It is almost the same as cflow, but unlike cflow, the join point P selected by the pointcut of the argument is not selected.

** Difference between within code and cflow **

withincode

withincode.java


call(void Main.hogeB()) && withincode(void Main.init())

Since withincode is a join point that occurs in the body of the method that matches the argument pattern In this case, only the join point where the method called main.hogeA is called So there is no match for call (void Main.hogeB ())

cflow

cflow.java


call(void Main.hogeB()) && cflow(call(void Main.init()))

Since cflow selects all the join points that occur between the start and end of the join point P selected by the argument pointcut. In this case, the join point where the methods main.hogeA and main.hogeB are called Therefore, there is something that matches call (void Main.hogeB ()).

qiita10.PNG

** Advice-related pointcuts **

The call pointcut selects the "when" when the method specified in the method pattern is called as the join point. This join point is not only for methods, but also for method calls that appear in the aspect definition. This also applies to pointcuts other than call.

Infinite recursive call problem

Hello.java


impoort java.io.*;
aspect Tracer {
  pointcut tracedMethods(): call(* PrintStream.println(..));

  before(): tracedMethods() {
    System.out.println("** method call");
  }
}

public class Hello {
  public static void say() {
    System.out.println("Hello");
  }
  public static void main(String[] args) {
    say();
  }
}

Writing a program like the one above would result in an infinite loop

qiita11.PNG

To avoid this problem, there is ** advice execution ** in the advice related pointcut Represents the "time" when the body of any advice is being executed without taking any arguments

Sample.java


!cflow(adviceexecution())
//Select all join points except while running the body of advice

** Pointcut to retrieve contextual information **

There are three pointcuts related to program execution context information: ** this **, ** target **, and ** args **.

:black_small_square:this Select all join points that occur in the body of a method or constructor running by an instance of a type (including subclasses and subinterfaces) that matches the pointcut arguments Any type of join point

:black_small_square:target Select all method calls and field access for instances of types (including subclasses and subinterfaces) that match the pointcut arguments as join points. Any type of join point

:black_small_square:args Select a method or constructor call that takes an argument of the type that matches the pointcut argument as the join point.

** How to use this pointcut **

Select a join point when the class of the object pointed to by this variable matches the pointcut argument

Sample.java


call(* *(..)) && this(Session)
//The above selects the call of any method from the methods of the Session class or its subclass as a join point.

** How to use target pointcut **

Select a join point when it matches the class type and pointcut arguments of the object being targeted for method invocation or field access

Sample.java


class Session {}
class BookSession extends Session{} 

Sample.java


call(* Session.*(..)) && target(BookSession)
//The above selects only when calling the method declared in the Session class as the join point when calling on the BookSession object.

Session s = new BookSession(301);
s.doIt();

** How to use args pointcut **

Sample.java


call(* *(..)) && args(BookSession, ..)
//Select a method call as the join point whose first argument is an instance of the BookSession class

Note that the args pointcut also uses the actual type of the argument object when looking up the type.

** Pointcut using Boolean expression **

** Named pointcut **

reference

Recommended Posts

List of point cuts for making finer point cuts
A list of rawValues for UITextContentType.
List of alternative distributions for CentOS
List of download destinations for oracle java
List of libraries useful for ios application development
Get a list of MBean information for Java applications
Tips for making good use of Canvas in Xcode
Output a list of cron settings for all users.
List of frequently used Java instructions (for beginners and beginners)
List of MySQL sentences for programming beginners * Personal memo
List of beginners (List) memo
Microbenchmark for integer power of floating point numbers in Ruby