循环引用属性操作:

1)AbstractAutowireCapableBeanFactory类中的allowCircularReferences被设置为了false。

2)代码:

AnnotationConfigApplicationContext a = new AnnotationConfigApplicationContext("");

a.setAllowCircularReferences();

spring初始化过程

1 初始化spring上下文,new DefaultListBeanFactory()

2 之后调用refresh()

3 refresh()中包含了springBean初始化的全部过程

4 完成spring扫描所有的Bean,在invokeBeanFactoryPostProcessors()

5 其中最核心的初始化方法是finishBeanFactoryInitialization(传入beanFactory)

6 之后继续调用preInstantiateSingletons,进入初始化的准备。

7 核心方法继续调用getBean,因为getBean才会真正的初始化Bean。那么在getBean中会调用两次getSingleton方法,“第一次调用是解决Bean相互引用问题,第二个参数默认传递为true”。

8 首次调用getSingleton基本会返回null因为这个时候 bean没有被创建成功,所以在singleobjectsMap中还没有办法找到创建成功的Bean,这个时候继续会判断当前Bean的是否处于创建状态,如果是的话从earlySingletonObjectsMap中获取一定获取的到;如果不在创建状态,那么这个时候首次调用返回null。
***在这里说明下,bean在最开始仅仅是个“创建中”的状态,也就是单独创建了对象,但是依赖注入还没有做,这样的对象会放入earlySingletonObjectsMap中!

9 二次调用getSingleton方法,初始化bean的时候还会检查singleobjectsMap集合,如果仍然获取不到则去执行createBean方法创建对象,委托模式调用了doCreateBean方法的createInstance方法创建了wapper对象。

9.1 其实在这里创建的包装对象还仅仅是一个java对象,还没有进行属性的注入因为注入要通过populateBean方法处理。

ps:spring的BeanFactory后置处理器共有8个。

10 注入方法是通过 populateBean 方法开始执行的,遇到@Autowired属性则通过BeanFactory的后置处理器找到相应的BeanDefine再次调用getBean方法执行第6步骤即可。

10.1 populateBean 方法执行时首先判断当前类需不需要注入;

10.2 调用doCreateBean之后在调用initializeBean方法,该方法中使用“策略模式”对Bean的继承接口进行扩展;

10.3 initializeBean方法中的invokeAwareMethods方法会回调Bean实现了以下接口的方法:BeanNameAware,BeanClassLoaderAware,BeanFactoryAware

private void invokeAwareMethods(String beanName, Object bean) {
if(bean instanceof Aware) {
if(bean instanceof BeanNameAware) {
((BeanNameAware)bean).setBeanName(beanName);
} if(bean instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware)bean).setBeanClassLoader(this.getBeanClassLoader());
} if(bean instanceof BeanFactoryAware) {
((BeanFactoryAware)bean).setBeanFactory(this);
}
} }

10.4 往下跟踪applyBeanPostProcessorsBeforeInitialization方法中继续使用Bean的后置处理器,回调对应接口的方法:

    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
Iterator var4 = this.getBeanPostProcessors().iterator(); do {
if(!var4.hasNext()) {
return result;
} BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
result = beanProcessor.postProcessBeforeInitialization(result, beanName);
} while(result != null); return result;
} @Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null; if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
} if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
} return bean;
}

ps:之前提到过两次getSingleton方法是为了处理Bean相互引用的问题的答案也就渐渐浮出水面;如下图:

最新文章

  1. httpd 安装
  2. Java多线程系列--“JUC原子类”04之 AtomicReference原子类
  3. URL编码数据转换为JSON数据
  4. Sql Server Profiler保存与重演跟踪
  5. Android 之夜间模式(多主题)的实现
  6. 【HDOJ】1513 Palindrome
  7. CURL 宏定义列表
  8. CF 161D Distance in Tree【树DP】
  9. 04_Javascript初步第二天(上)
  10. 如何在jenkins上新建一个项目及其简单配置
  11. 前端架构师 摘自《前端架构设计》-micah godbolt
  12. 【tool】部署前端工具
  13. 指定的 CGI 应用程序遇到错误,服务器终止了该进程。
  14. 自定义xUtils框架
  15. HTML之间互相传参
  16. gradle 打包springboot项目,找不到项目jar application.class
  17. spring cloud 微服务日志跟踪 sleuth logback elk 整合
  18. 【数学】NOIP数论内容整理
  19. java-部分精选面试题
  20. java之平台无关

热门文章

  1. 利用GitHub+Node.js+Hexo搭建个人博客
  2. ES6函数的个人总结
  3. TED演讲:真正拉开你与周围人之间差距的,是自学能力https://www.bilibili.com/video/av65904878/?spm_id_from=333.788.videocard.1
  4. oracle的一些状态查询
  5. JavaScript高级程序编程(三)
  6. jmeter(四十四)常用性能指标分析
  7. 微信小程序之使用wx:for遍历循环
  8. 刷题记录:[De1ctf] shell shell shell
  9. node.js使用cluster实现多进程
  10. hadoop平台上HDFS和MAPREDUCE的功能、工作原理和工作过程