<> background

Today, I met a colleague in the analysis springboot The problem caused by using the annotation and method lock of (@Transaction and synchronized In the same method, the transaction enters before the lock and releases after the lock ) I suddenly thought about it spring Of Aspect What is the execution sequence , This article introduces java One of them (InvocationHandler) The method of implementing agent by dynamic agent , So we can infer the similar mechanism spring In fact, the facet of is also the function that executes the facet in the proxy class invoke Before or after executing the defined point , The reason why we can scan the section automatically is similar spring
rabbitmq The realization of sweeping all over again component
bean Get all the comments and execute , Further careful analysis Aspect The realization of , In this paper, we try to realize aspect Annotation so as to capture the parameters before and after the execution of the function and print them out

<> code
package com.oujiangping.leetcode; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) public @interface aspect { } package
com.oujiangping.leetcode; @aspect public interface TestAspect { public String
test(String sr); } package com.oujiangping.leetcode; @aspect public class
TestAspectImpl implements TestAspect { @Override public String test(String sr)
{ System.out.println("run TestAspectImpl.test " + sr); return sr; } } package
com.oujiangping.leetcode; @aspect public class TestAspectImplA implements
TestAspect { @Override public String test(String sr) { System.out.println("run
TestAspectImplA.test " + sr); return sr; } } package com.oujiangping.leetcode;
package com.oujiangping.leetcode; import java.lang.reflect.Field; import
java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import
java.lang.reflect.Proxy; public class MyAspect implements InvocationHandler {
Object instance; public Object aspect(Object instance) { this.instance =
instance; return Proxy.newProxyInstance(instance.getClass().getClassLoader(),
instance.getClass().getInterfaces(),this); } public void befor(Method method,
Object[] args) { System.out.println("~~~~ befor: " + method.getName() + " " +
args); } public void after(Object object) { System.out.println("~~~~ after: " +
object); } public static void init() { Field[] fields=
MyAspect.class.getDeclaredFields(); for(int i=0;i<fields.length;i++){ MyAspect
myAspect = new MyAspect(); aspect aspects =
fields[i].getType().getAnnotation(aspect.class); if(aspects != null) {
fields[i].setAccessible(true); try { fields[i].set(myAspect, new
MyAspect().aspect(fields[i].get(myAspect))); } catch (IllegalAccessException e)
{ e.printStackTrace(); } } } } @Override public Object invoke(Object proxy,
Method method, Object[] args) throws Throwable { Object result=null;
befor(method, args); result = method.invoke(instance, args); after(result);
return null; } public static TestAspect testAspect = new TestAspectImpl();
public static TestAspect testAspectA = new TestAspectImplA();; public static
void main(String []args) { init(); testAspect.test("I'm TestAspectImpl");
testAspectA.test("I'm TestAspectImplA"); } } result : ~~~~ befor: test
[Ljava.lang.Object;@49476842 run TestAspectImpl.test I'm TestAspectImpl ~~~~
after: I'm TestAspectImpl ~~~~ befor: test [Ljava.lang.Object;@78308db1 run
TestAspectImplA.test I'm TestAspectImplA ~~~~ after: I'm TestAspectImplA
<> summary