我们发现,这里有个循环,迭代的是this.getBeanPostProcessors()的结果,我们看看这个是什么,是List,下图是这个list的数据
经过几次debug发现当BeanPostProcessor为第四个元素时AnnotationAwareAspectJAutoProxyCreator,result变成了代理类。关键就是在processor.postProcessAfterInitialization()这个方法,把断点打进去。
发现没有AnnotationAwareAspectJAutoProxyCreator这个实现类
那就看看这个AnnotationAwareAspectJAutoProxyCreator的父类吧,Ctrl + Alt + Shift + U查看AnnotationAwareAspectJAutoProxyCreator的类图依赖关系
发现AbstractAutoProxyCreator在上上个图中,并且AnnotationAwareAspectJAutoProxyCreator没有重写postProcessAfterInitialization方法,所以我们就看AbstractAutoProxyCreator的这个方法。
打断点时发现Object bean不是代理类,那就看看org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary方法。在这个方法中调用了createProxy()创建代理类,进去看下。
这个方法最后return proxyFactory.getProxy(getProxyClassLoader());进入getProxy方法看看
所以createAopProxy()方法返回AopProxy类型的实例,有俩实现类可供创建CglibAopProxy和JdkDynamicAopProxy,及cglib和jdk动态代理两种。
那么究竟创建哪一种,就是我们今天要看的关键之处,所以我们进入createAopProxy()方法看看。
再进去org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy方法看看。
config.isOptimize()和config.isProxyTargetClass()都默认false
这里创建logincontroller时config的数据如下
然后判断targetClass是否为接口,这里我们的LoginController不是接口,就走了下面的return
所以Spring AOP使用JDK动态代理还是cglib取决于是否是接口,并没有默认的方式。
我们改一下LoginController让其实现接口
debug启动,这时得到的代理类就是JDK动态代理。
为什么JDK动态代理必须是接口?
我们看一下这个问题,首先把LoginController改为实现ILoginBaseController接口,然后根据咱们上面的debug分析,在
org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)方法里createAopProxy().getProxy就是我们解决这个问题的入口,我们在getProxy里打上断点,
JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)方法里断点加到return语句上
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);然后在Proxy.newProxyInstance进来加断点,一步步往下走,在719行是关键