循环引用属性操作:
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相互引用的问题的答案也就渐渐浮出水面;如下图: