How to use the notification type of spring AOP and create notifications
Write at the front
1. There are six notification types in spring AOP. As long as we customize a class to implement the corresponding interface, they are all org springframework. In the AOP package.
2. The connection points of AOP can be method calls, method calls themselves, class initialization and object instantiation, but spring AOP is full of method calls, which is simpler and most practical
Write a public class for the target object
public class Person { private String name; public boolean saySomething(String something){ System.out.println("Pereson类中说了一句:"+something); return true;//默认返回true } public String getName() { return name; } public void setName(String name) { this.name = name; } }
1、 Create a pre notification (that is, execute before the target method call)
The pre notification can modify the parameters passed to the method, and can prevent the execution of the method by throwing an exception. The pre notification can be used to verify the user's login, which is what spring security does
1. Example: before a method is executed, write the message containing the method name to the console, and modify the passed in parameters. (the content written in the article is relatively small. Most of them have comments in the code. You can download the code to view it.)
/** * 前置通知类 */ public class BeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method,Object[] objects,@Nullable Object o) throws Throwable { //第一个参数是目标方法对象,第二个是参数,第三个是做为调用目标的object(这是personr实例) //打印方法名 System.out.println("要执行的方法是:"+method.getName()); //修改参数为lyn4ever objects[0]="lyn4ever";//我们修改成为了lyn4ever,所以打印出来的就是lyn4ever,而不是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(); //我这里传的参数是zhangsan,理论上它应该打印出来zhangsan proxy.saySomething("zhangsan"); } }
No problem. I originally 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, it cannot modify the parameters or return value as above. However, it can throw exceptions that can be sent to the stack, and it can also call other methods.
/** * 后置返回通知 */ public class AfterReturnAdvice implements AfterReturningAdvice { @Override public void afterReturning(@Nullable Object o,Method method,@Nullable Object o1) throws Throwable { /* 参数和前置通知是一样的 这个是在返回之后调用,因此,person中的saySomething会先打印,我们在这里修改的参数不起作任何作用 */ System.out.println("调用的方法是:"+method.getName()+"这句是在saySomething之后");//这句是在saySomething之后 objects[0]="lyn4ever";//这句可以修参数,但是之前的方法已经执行过了,所以不起任何作用 System.out.println("我们修改了参数为:"+objects[0]+"但是没有任何用");//这时候这个参数并不会传到person.saysomething(),因为已经调用过了 } public static void main(String[] args) { Person person = new Person(); ProxyFactory pf = new ProxyFactory(); pf.addAdvice(new AfterReturnAdvice());//注意修改这个为当前类中的通知类 pf.setTarget(person); Person proxy = (Person) pf.getProxy(); proxy.saySomething("zhangsan"); } }
3、 Surround notification
This person's best understanding is that the code can be executed before and after the method call. 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 implemented by it is object, so we can modify it, while the return value of the pre notification is void, so we can't modify it. Even so that we can not call the connection point method in the target object, and we can completely modify all the code of this method.
public class MyMethodInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { return null; } }
Although the invoke () method does not provide parameters like those before, this invocation instance can be obtained
Code example
/** * 环绕通知 */ public class MyMethodInterceptor implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { //在这个invoation中有一切我们想要的方法相关 System.out.println("类名是:"+invocation.getThis().getClass().getName()); System.out.println("目标方法是:"+invocation.getmethod().getName()); Object[] arguments = invocation.getArguments();//这个就是参数 System.out.println("第一个参数 是:"+arguments[0]); //我们修改第一个参数为lyn4ever arguments[0]="lyn4ever"; invocation.proceed();//执行目标方法 System.out.println("这个是在之后执行的"); return false;//修改返回值 } public static void main(String[] args) { Person person = new Person(); ProxyFactory pf = new ProxyFactory(); pf.addAdvice(new MyMethodInterceptor());//注意修改这个为当前类中的通知类 pf.setTarget(person); Person proxy = (Person) pf.getProxy(); boolean flag = proxy.saySomething("zhangsan"); System.out.println(flag);//方法本来是要返回true的 } }
As you can see, we modified the value returned by the target method.
The demo of this article 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 value for your study or work. Thank you for your support.