宁波网站建设佳选蓉胜网络好,做娱乐网站需要哪些,如何开发移动网站,公司做影视网站侵权假设有两个类A和B B是A的成员变量#xff0c;A也是B的成员变量。 假设类A的bean为a#xff0c;类B的bean为b。且IOC容器先处理A。 熟悉Spring容器初始化的同学#xff0c;应该都知道#xff0c;容器初始化的过程中#xff0c;bean的创建是如下触发的#xff1a; getBean… 假设有两个类A和B B是A的成员变量A也是B的成员变量。 假设类A的bean为a类B的bean为b。且IOC容器先处理A。 熟悉Spring容器初始化的同学应该都知道容器初始化的过程中bean的创建是如下触发的 getBean 的时候发现不存在就去 createBean。 bean的创建是在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean 完成的。
doCreateBean 大致可以分为三步 1、实例化beancreateBeanInstance 2、填充属性populateBean 3、初始化beaninitializeBean protected Object doCreateBean(String beanName, RootBeanDefinition mbd, Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.BeanWrapper instanceWrapper null;// 实例化beanif (instanceWrapper null) {instanceWrapper createBeanInstance(beanName, mbd, args);}......boolean earlySingletonExposure (mbd.isSingleton() this.allowCircularReferences isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {// 放入3级缓存addSingletonFactory(beanName, () - getEarlyBeanReference(beanName, mbd, bean));}......try {// 填充属性populateBean(beanName, mbd, instanceWrapper);// 初始化beanexposedObject initializeBean(beanName, exposedObject, mbd);}...... return exposedObject;}其中第三步只是Spring框架提供的 InitializingBean 接口的扩展用于设置完properties之后做一些动作对循环依赖没有影响。 循环依赖的处理只发生在第一步和第二步。
从以上代码可以看到当A类的一个单例对象a被实例化之后被立即放在了3级缓存内具体的代码如下 /*** Add the given singleton factory for building the specified singleton* if necessary.* pTo be called for eager registration of singletons, e.g. to be able to* resolve circular references.* param beanName the name of the bean* param singletonFactory the factory for the singleton object*/protected void addSingletonFactory(String beanName, ObjectFactory? singletonFactory) {Assert.notNull(singletonFactory, Singleton factory must not be null);synchronized (this.singletonObjects) {if (!this.singletonObjects.containsKey(beanName)) {// 放入3级缓存this.singletonFactories.put(beanName, singletonFactory);// 从2级缓存中移除确保2级缓存没有this.earlySingletonObjects.remove(beanName);// 标记这个bean已经创建过this.registeredSingletons.add(beanName);}}}在给a设置属性B的时候去对B进行 getBean 发现不存在也会对B进行 createBean 。 类B的对象b在实例化之后也会进行属性的设置会对类A进行 getBean 这部分就有了差异。
SuppressWarnings(unchecked)protected T T doGetBean(String name, Nullable ClassT requiredType, Nullable Object[] args, boolean typeCheckOnly)throws BeansException {String beanName transformedBeanName(name);Object beanInstance;// 这里去获取A的单例bean// Eagerly check singleton cache for manually registered singletons.Object sharedInstance getSingleton(beanName);if (sharedInstance ! null args null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace(Returning eagerly cached instance of singleton bean beanName that is not fully initialized yet - a consequence of a circular reference);}else {logger.trace(Returning cached instance of singleton bean beanName );}}beanInstance getObjectForBeanInstance(sharedInstance, name, beanName, null);}getSingleton 的代码如下 /*** Return the (raw) singleton object registered under the given name.* pChecks already instantiated singletons and also allows for an early* reference to a currently created singleton (resolving a circular reference).* param beanName the name of the bean to look for* param allowEarlyReference whether early references should be created or not* return the registered singleton object, or {code null} if none found*/Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {// Quick check for existing instance without full singleton lock// 从1级缓存拿Object singletonObject this.singletonObjects.get(beanName);if (singletonObject null isSingletonCurrentlyInCreation(beanName)) {// 从2级缓存拿singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null allowEarlyReference) {synchronized (this.singletonObjects) {// Consistent creation of early reference within full singleton locksingletonObject this.singletonObjects.get(beanName);if (singletonObject null) {singletonObject this.earlySingletonObjects.get(beanName);if (singletonObject null) {// 从3级缓存拿ObjectFactory? singletonFactory this.singletonFactories.get(beanName);if (singletonFactory ! null) {singletonObject singletonFactory.getObject();// 放入2级缓存this.earlySingletonObjects.put(beanName, singletonObject);// 从3级缓存中移除this.singletonFactories.remove(beanName);}}}}}}return singletonObject;}因为前面类A执行 doCreateBean 的时候已经放进了3级缓存所以b在设置属性的时候是能拿得到a的。 这里的拿到的a还仅仅是执行了实例化的并没有设置完属性。
b在执行完第二步设置属性第三步初始化之后又返回到a的第二步设置属性第三步初始化。 至此类A的对象a和类B的对象b都已经创建成功。
最终总结流程图如下