How to use the notification type of spring AOP and create notification

Time:2021-7-20

Write at the front

1. There are six notification types in spring AOP. As long as we define a class to implement the corresponding interface, they are all in the org.springframework.aop package.

2. The connection points of AOP can be method call, method call itself, class initialization and object instantiation, but spring AOP is full of method call, which is simpler and most practical

Notification name Interface
Before advice org.springframework.aop.MethodBeforeAdvice
Post return notification org.springframework.aop.AfterReturningAdvice
Post notification org.springframework.aop.AfterAdvice
Around Advice org.springframework.aop.MethodInterceptor
Exception notification org.springframework.aop.ThrowsAdvice
Introduction notice org.springframework.aop.IntroductionInterceptor

Write a public class for the target object

public class Person {
 private String name;
 public boolean saySomething(String something){
  System. Out. Println ("there is a sentence in the pereson class: + something");
return true;// Return true by default
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}

1、 Create pre notification (that is, execute before the target method is called)

Pre notification can modify the parameters passed to the method, and can prevent the execution of the method by throwing an exception. Pre notification can be used to verify the user’s login, which spring security does

1. Example: before a method is executed, the message containing the method name is written to the console, and the incoming parameters are modified( The content of the article is relatively small, most of them have comments in the code, you can download the code to see)

/**
 *Pre notification class
 */
public class BeforeAdvice implements MethodBeforeAdvice {


 @Override
 public void before(Method method, Object[] objects, @Nullable Object o) throws Throwable {
   //The first parameter is the target method object, the second is the parameter, and the third is the object as the call target (this is the personr instance)
  //Print method name
  System. Out. Println ("the method to be executed is: + method. Getname());
  //Modify the parameter to lyn4ever
  objects[0]="lyn4ever";// We changed it to lyn4ever, so what we printed out is lyn4ever, not Zhangsan
 }


 public static void main(String[] args) {
  Person person = new Person();

  ProxyFactory pf =new ProxyFactory();
  pf.addAdvice(new BeforeAdvice());
  pf.setTarget(person);

  Person proxy = (Person) pf.getProxy();

  //The parameter I pass here is Zhangsan. Theoretically, it should be printed out
  proxy.saySomething("zhangsan");
 }
}

No problem. Originally, I entered Zhangsan, and changed the parameter to lyn4ever in AOP, which is a perfect replacement.

2、 Post return notification

It is executed after the connection point (method call) returns. Obviously, you can’t modify the parameters or the return value as above. But you can throw an exception that can be sent to the stack, and you can call other methods as well.

/**
 *Post return notification
 */
public class AfterReturnAdvice implements AfterReturningAdvice {

 @Override
 public void afterReturning(@Nullable Object o, Method method, Object[] objects, @Nullable Object o1) throws Throwable {
  /*
  The parameters are the same as the pre notification
  This is called after the return, so the saySomething in person will be printed first, and the parameters we modify here will not play any role.
   */

  System. Out. Println ("the calling method is: + method. Getname() +" this sentence is after saysomething ")// This is after say something
  objects[0]="lyn4ever";// This sentence can fix parameters, but the previous method has been implemented, so it doesn't work

  System. Out. Println ("we modified the parameter to be" + objects [0] + "but it's useless")// At this time, this parameter will not be passed to person. Saysomething (), because it has already been called

 }


 public static void main(String[] args) {
  Person person = new Person();

  ProxyFactory pf = new ProxyFactory();
  pf.addAdvice(new AfterReturnAdvice());// Notice to change this to the notification class in the current class
  pf.setTarget(person);

  Person proxy = (Person) pf.getProxy();
  proxy.saySomething("zhangsan");
 }
}

3、 Surround notification

The best way to understand this is to execute code before and after method calls. It looks like a pre post collection, but it can modify the return value of the method, because the return value of the invoke method it implements is object, so we can modify it, while the return value of the pre notification is void, so we can’t modify it. Even if we don’t call the join point method in the target object, we can completely modify the whole code of this method.


public class MyMethodInterceptor implements MethodInterceptor {
 @Override
 public Object invoke(MethodInvocation invocation) throws Throwable {
  return null;
 }
}

Although this invoke () method does not provide parameters like those before, this instance of invocation can be obtained

Code examples

/**
 *Surround notification
 */
public class MyMethodInterceptor implements MethodInterceptor {
 @Override
 public Object invoke(MethodInvocation invocation) throws Throwable {
  
  //In this invocation, there is everything we want to do
  System. Out. Println ("class name is: + invocation. Getthis(). Getclass(). Getname());
  System. Out. Println ("target method is: + invocation. Getmethod(). Getname());

  Object[] arguments = invocation.getArguments();// This is the parameter
  System. Out. Println ("the first parameter is: + arguments [0]);

  //We change the first parameter to lyn4ever
  arguments[0]="lyn4ever";


  invocation.proceed();// Implementation target method


  System. Out. Println ("this is executed later");

  return false;// Modify return value
 }


 public static void main(String[] args) {
  Person person = new Person();

  ProxyFactory pf = new ProxyFactory();
  pf.addAdvice(new MyMethodInterceptor());// Notice to change this to the notification class in the current class
  pf.setTarget(person);

  Person proxy = (Person) pf.getProxy();
  boolean flag = proxy.saySomething("zhangsan");
  System.out.println(flag);// Method was meant to return true
 }
}

As you can see, we have modified the value returned by the target method.

This demo has been submitted to GitHub

summary

The above is the whole content of this article, I hope the content of this article has a certain reference learning value for your study or work, thank you for your support to developer.

Recommended Today

MSSQL · query and sort the records of all tables in a database

Reading time |0.27 minutes word count |444 characters primary coverage |1. Introduction & background “MSSQL · query and sort the records of all tables in a database” Author | SCscHero Writing time | 2021/7/13 PM10:0 Article type |Series Degree of completion |Completed motto Every great cause has a trivial beginning. 1、 Introduction & background    Completion: […]