猜测
1. 在容器启动时创建
2.在getBean时创建
分析源码,在调用getBean方法时,会从singletonObjects中根据beanName获得对应的代理对象,取出的singletonObject已经是代理对象了,所以可以说明在容器启动时代理对象就已经生成了.
下面是我分析源码思路
1.因为这个代理是从singletonObjects这个容器来的,所以我需要查找这个容器的put方法在哪调用,看看这个代理类是什么时候被放入容器中的
2.找到调用方法,打上断点
3. 通过调用链路可得 代理对象是在DefaultSingletonBeanRegistry#getSingleton中被set进去
5.从上面可得先从singletonObjects容器中尝试拿 如果没有的话再调用参数singletonFactory的getObject方法去获得
6.那么可以看看singletonFactory的getObject在哪传入的参数
7.再进入createBean,可以看到doCreateBean返回了代理对象,
此处的doCreateBean对象其实就是springIOC 创建bean的过程 可参考(https://www.jianshu.com/p/557a87dfdef9)
8. 在spring生命周期中,有一个初始化bean方法initializeBean(),其中有一个bean的后置处理器回调applyBeanPostProcessorsAfterInitialization ,因为spring内置了很多实现了BeanPostProcessor#postProcessAfterInitialization接口的后置处理器,那么在后置处理回调中会一个一个执行后置处理
9.在内置的后置处理器中,有一个后置处理器叫做AnnotationAwareAspectJAutoProxyCreator,其后置处理器逻辑中调用了wrapIfNecessary()方法
10.在wrapIfNecessary方法中,可以看到createProxy方法,在其方法中最后一步有一个getProxy方法来获取代理
11.可以看到最后的getProxy中调用了createAopProxy().getProxy()方法 并且将classLoader作为参数传入
12.点开getProxy方法可以看出,其有两个实现类 一个就是JDK方式,一个就是Cglib方式
13. 以JDK方式为例子,点进去看,可以看到最后调用的是JDK的Proxy.newProxyInstance方法来生成动态代理,CGLIB则是调用ASM来实现动态代理的