一、Spring容器启动流程
创建配置类
@ComponentScan(value ={"com.woniu"})@ConfigurationpublicclassMyConfig{}
创建一个普通类
packagecom.woniu.service;importorg.springframework.stereotype.Component;@ComponentpublicclassEservice{}
创建一个启动类
publicclassApplication{publicstaticvoidmain(String[] args){AnnotationConfigApplicationContext context =newAnnotationConfigApplicationContext(MyConfig.class);}}
在启动类的第三行打断点开始单步调试,进入spring的容器启动流程
这个方法非常重要,在循环依赖中对于同一个bean会多次调用,先从一级缓存中查询是否存在bean,若不存在,再从二级缓存中查询是否存在bean,如果还是没有找到,从三级缓存中查询singletonFactory,如果没有,则直接返回,若在三级缓存中找到singletonFactory,则调用工厂中的方法创建bean,然后在把bean添加到二级缓存中
什么是三级缓存
二、简单依赖注入
再创建一个普通类
packagecom.woniu.service;importorg.springframework.stereotype.Component;@ComponentpublicclassFservice{}
修改一下Eservice,注入Fservice实例
packagecom.woniu.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;@ComponentpublicclassEservice{@AutowiredprivateFservice fservice;}
在这个populateBean里面注入Fservice的实例到Eservice中
上面截图中的descriptor.resolveCandidate方法继续跟踪会进入到下面截图的方法,注意,这时候,需要从容器中查找Fservice的实例对象了
下面就正式进入创建一个Fservice对象的实例,并且添加到spring的容器中,也就是第一部分讲的spring容器启动流程
把创建好的fservice实例返回给刚才正在处理@Autowired的注解的代码
程序继续运行,把eservice也加入到一级缓存
三、AOP依赖注入
修改MyConfig
packagecom.woniu;importorg.springframework.context.annotation.ComponentScan;importorg.springframework.context.annotation.Configuration;importorg.springframework.context.annotation.EnableAspectJAutoProxy;@ComponentScan(value ={"com.woniu"})@EnableAspectJAutoProxy@ConfigurationpublicclassMyConfig{}
创建MyAop类
importorg.aspectj.lang.annotation.Aspect;importorg.aspectj.lang.annotation.Before;importorg.aspectj.lang.annotation.Pointcut;importorg.springframework.stereotype.Component;@Component@AspectpublicclassMyAop{//用来定义切入点表达式的方法,方法名就是切入点表达式的名称@Pointcut("execution(* com.woniu.service..*.*(..))")publicvoidpt1(){}@Before("pt1()")publicvoidBefore()throwsThrowable{System.out.println("before aop...");}}
Eservice
packagecom.woniu.service;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;@ComponentpublicclassEservice{@AutowiredprivateFservice fservice;}
Fservice
packagecom.woniu.service;importorg.springframework.stereotype.Component;@ComponentpublicclassFservice{publicvoidprint(){System.out.println("fservice");}}
启动类
packagecom.woniu;importcom.woniu.service.*;importorg.springframework.context.annotation.AnnotationConfigApplicationContext;importorg.springframework.context.annotation.EnableAspectJAutoProxy;publicclassApplication{publicstaticvoidmain(String[] args){AnnotationConfigApplicationContext context =newAnnotationConfigApplicationContext(MyConfig.class);}}
此时fservice的原生bean已经实例已经创建完成,initializeBean这个方法将会做初始化,在这里,将会给fservice生成一个代理对象
这个BeanPostProcessor会为Fservice生成代理对象,并且放置在二级缓存
earlyProxyReferences可以帮助判断是否已经生成过代理对象,wrapIfNecessary这个方法就是生成代理对象的方法
创建代理工厂
fservice的代理对象已经被创建出来
initializeBean方法调用完毕,Fservicve代理对象创建完毕
此时的一级缓存如下
至此Eservice对象的initializeBean方法执行完毕,fservice的代理对象已经被注入到eservice中
四、循环依赖
- 非单例V.S非单例
- 单例构造函数V.S单例构造函数
- 单例构造函数V.S单例普通依赖注入
- 单例普通依赖注入V.S单例普通依赖注入
- AOP单例普通依赖注入V.SAOP单例普通依赖注入****
五、相关代码
相关代码
版权归原作者 皇家大少つ 所有, 如有侵权,请联系我们删除。