<>背景

今天在分析同事遇到一个springboot的注解和方法锁一起用而导致的问题(@Transaction和synchronized用在同一个方法中由于事务先于锁进入后于锁释放而可能引发的数据问题)中而突然思考到spring的Aspect是怎么样的执行顺序,本文介绍java中其中一种(InvocationHandler)利用动态代理的方式实现的代理的方法,从而类似的机制我们推测出spring的切面其实也是在代理类中执行了切面的函数并在invoke之前或者之后去执行定义的点,而之所以能够自动扫描切面应该是类似spring
rabbitmq的实现扫面一遍所有的component
bean获取所有的注解然后执行,后续再仔细分析Aspect的实现,本文我们尝试实现aspect注解从而实现捕获函数执行前参数和执行后结果并打印出来

<>代码
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"); } } 结果: ~~~~ 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
<>总结

技术
下载桌面版
GitHub
Gitee
SourceForge
百度网盘(提取码:draw)
云服务器优惠
华为云优惠券
腾讯云优惠券
阿里云优惠券
Vultr优惠券
站点信息
问题反馈
邮箱:[email protected]
吐槽一下
QQ群:766591547
关注微信