再看doGetBean(org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean)
第120行sharedInstance已经变成了代理类
所以我们进入org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)方法看看,重新运行,然后再加个断点,打到org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)里。
走过88行后,singletonObject变成了代理类,所以关键点就是在this.singletonObjects.get(beanName);
我们可以看到singletonObjects 是一个ConcurrentHashMap。原来IoC的实例在这个ConcurrentHashMap里。
private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
所以到这里我们就可以知道,这个代理类不是在getBean的时候生成的,即不是在启动类的第6行生成的,那就是在第5行生成的,即在IoC容器初始化时产生的代理类。
刚才那个ConcurrentHashMap是get的,那就肯定有put的时候。搜一下,还在这个类里,发现一个addSingleton方法,有俩地方调用,一个是在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton调用的,一个是在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
那就把断点打到这俩方法里,看会走到哪个,把别的断点都去掉,当然了,因为spring还有别的自己的实例要获取,IoC容器里还有spring自己的实例,所以这个断点要加上条件,当beanName是loginController时进去断点,这样就方便多了。我们只保留第5行的代码,因为getBean里面也会调getSingleton。
运行启动类,发现进入了getSingleton方法,但Object singletonObject = this.singletonObjects.get(beanName);返回的为null,所以继续往下走。发现在第127行返回了代理类,看这行的getObject方法又不知道是那个实现类,所以我们去左下角看方法栈,找一下这个方法的上一个方法,
就是左下角的第二个方法doGetBean,发现传的是一个匿名内部类,这个匿名内部类里调的是org.springframework.beans.factory.support.AbstractBeanFactory#createBean
所以我们把断点走完,进到这个createBean里打断点,同样加条件。
断点走过324行时变成代理类,即进入org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean看看,打个断点同样加条件
断点走过doCreateBean方法第380行后产生了代理类,所以把断点打到这个org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)方法里,同样加上条件,把别的断点去掉,重新运行。
当走过1240行时已经变成了代理类,所以把断点打到这个org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法,同样加上条件,把别的断点去掉,重新运行。