Spring,IOC源码分析

有错勿喷

1.首先是Spring,IOC的基本概念

  • IOC是一个容器
  • 容器启动的时候创建所有单实例对象
  • 我们可以直接从容器中获取到这个对象

2.调试流程

  • ioc容器的启动过程?启动期间都做了什么(什么时候创建所有单实例bean )
  • ioc是如何创建这些单实例bean ,并如何管理的;到底保存在了那里?

3.我们首先观察对象是什么时候创建的

  1. 我们可以先写一个实体类Person,并且写一个无参及有参构造器,并写上输出语句,这样我们就可以在创建Person对象的时候观察到
public class Person {
    private String name;
    public Person() {
        System.out.println("person构造");
    }
    getset方法。。。
    toString方法。。。
  1. 在容器中配置,创建一个Spring的配置文件
<bean id="person01" class="com.xj.bean.Person">
    <property name="name" value="xj"></property>
</bean>

4.接下来就可以开始我们的调试啦

1. 首先对于Spring,使用以下代码创建对象

ApplicationContext ioc = new ClassPathXMLApplicationContext("ioc.xml");

2. 进入创建ioc容器对象

ClassPathXMLApplicationContext.java中,调用另一个构造器

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

3. 在这个里当我们执行完refresh()方法后,可以观察到控制台打印了Person的构造器,我们可以知道,组件的创建在refresh中,所以我们进入refresh中

refresh();

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
			throws BeansException {
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
          refresh();
    }
}

4. finishBeanFactoryInitialization(beanFactory);

AbstractApplicationContext.java中,我们可以观察到在
finishBeanFactoryInitialization(beanFactory);之后会打印,我们再进入

        public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {

			prepareRefresh();
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
			prepareBeanFactory(beanFactory);
			try {
				postProcessBeanFactory(beanFactory);
				invokeBeanFactoryPostProcessors(beanFactory);
				registerBeanPostProcessors(beanFactory);
				initMessageSource();
				initApplicationEventMulticaster();
				onRefresh();
				registerListeners();

                              //在这里打印---
				**finishBeanFactoryInitialization(beanFactory);**

				finishRefresh();
			}
			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}
				destroyBeans();
				cancelRefresh(ex);
				throw ex;
			}
			finally {
				resetCommonCaches();
			}
		}
	}

5. beanFactory.preInstantiateSingletons();

AbstractApplicationContext.java中,我们可以再次观察到最后一句的时候打印
beanFactory.preInstantiateSingletons();,所以我们再进去

        protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(new StringValueResolver() {
				@Override
				public String resolveStringValue(String strVal) {
					return getEnvironment().resolvePlaceholders(strVal);
				}
			});
		}
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}
		beanFactory.setTempClassLoader(null);
		beanFactory.freezeConfiguration();
                //这里进入
		beanFactory.preInstantiateSingletons();
	}

6. preInstantiateSingletons();

这里就是我们重头戏的开始了

        @Override
	public void preInstantiateSingletons() throws BeansException {
		if (this.logger.isDebugEnabled()) {
			this.logger.debug("Pre-instantiating singletons in " + this);
		}
                //拿到所有要创建的bean的名字,也就是我们配置的bean的id,如上面我配置的<bean id="person01" class="com.xj.bean.Person">,也就是这个person01
                //如果有多个的话,就person01,person02,person03
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
                  
                //按照顺序创建bean
		for (String beanName : beanNames) {
                        //根据bean id 获取到bean的定义信息,如全类名,是否单实例,是否懒加载等等
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                        //判断bean是单实例,并且不是抽象,不是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                                //是否是实现了FactoryBean接口的bean,我们的person不是,所以看下面的else
				if (isFactoryBean(beanName)) {
					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}
					if (isEagerInit) {
						getBean(beanName);
					}
				}
                                //否则的话,执行getBean,我们进入getBean
				else {
					getBean(beanName);
				}
			}
		}
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged(new PrivilegedAction<Object>() {
						@Override
						public Object run() {
							smartSingleton.afterSingletonsInstantiated();
							return null;
						}
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

7. getBean();

AbstractBeanFactory.java中
getBean方法内部调用doGetBean()方法,我们再次进入

        @Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

8. doGetBean(name, null, null, false);

        @SuppressWarnings("unchecked")
	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		//先从已经注册的所有单实例bean中看有没有这个bean,第一次创建肯定是没有的,所以执行下面的else
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				String nameToLookup = originalBeanName(name);
				if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			try {
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);
                                //拿到创建当前bean之前需要提前创建(依赖)的bean,dependsOn,如果有就循环创建
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
                                                //这边再次调用getBean创建
						getBean(dep);
					}
				}
                                //这里就是真正的创建bean实例
				if (mbd.isSingleton()) {
                                        //调用getSingleton创建bean,见9
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								// Explicitly remove instance from singleton cache: It might have been put there
								// eagerly by the creation process, to allow for circular reference resolution.
								// Also remove any beans that received a temporary reference to the bean.
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					if (scope == null) {
						throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
					try {
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									afterPrototypeCreation(beanName);
								}
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						throw new BeanCreationException(beanName,
								"Scope '" + scopeName + "' is not active for the current thread; consider " +
								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
								ex);
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			try {
				return getTypeConverter().convertIfNecessary(bean, requiredType);
			}
			catch (TypeMismatchException ex) {
				if (logger.isDebugEnabled()) {
					logger.debug("Failed to convert bean '" + name + "' to required type '" +
							ClassUtils.getQualifiedName(requiredType) + "'", ex);
				}
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
		}
		return (T) bean;
	}

9. getSingleton(beanName, new ObjectFactor。。。

从容器中取的名字为beanName的对象,如果不存在就创建,否则就直接从容器中拿

        public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(beanName, "'beanName' must not be null");
		synchronized (this.singletonObjects) {
                        //先从一个地方将bean get出来
                        //这个singletonObjects就是一个map,里面保存所有的单实例对象,也就是我们的容器
                        //如果容器中有的话,就不会创建
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
				if (this.singletonsCurrentlyInDestruction) {
					throw new BeanCreationNotAllowedException(beanName,
							"Singleton bean creation not allowed while singletons of this factory are in destruction " +
							"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
				}
				if (logger.isDebugEnabled()) {
					logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
				}
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<Exception>();
				}
				try {
                                        //bean创建,利用反射创建对象
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					// Has the singleton object implicitly appeared in the meantime ->
					// if yes, proceed with it since the exception indicates that state.
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						throw ex;
					}
				}
				catch (BeanCreationException ex) {
					if (recordSuppressedExceptions) {
						for (Exception suppressedException : this.suppressedExceptions) {
							ex.addRelatedCause(suppressedException);
						}
					}
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
                                        //将刚创建好的bean添加到singletonObjects中
					addSingleton(beanName, singletonObject);
				}
			}
			return (singletonObject != NULL_OBJECT ? singletonObject : null);
		}
	}

4. ioc实质

我们刚才已经看到了一个ioc容器
singletonObjects:
缓存所有单实例的对象,对象名->对象实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256);

IOC容器之一:保存单实例bean的地方;
IOC就是众多map的集合

posted @ 2020-09-11 22:37  微花  阅读(134)  评论(0编辑  收藏  举报

Loading