Spring源码分析系列——bean创建过程分析(一)——默认无参构造方法创建bean

前言

  • spring创建bean的方式
  • 从单例bean创建入手
    • getBean()方法解析
      • doGetBean()方法解析
        • createBean()方法解析
          • doCreateBean()方法解析
            • createBeanInstance()方法解析
            • instantiateBean()方法解析
            • instantiate()方法解析
            • instantiateClass()方法解析
  • 总结

spring创建bean的方式有很多种,其中最简单的是无参构造方法创建bean的方式,本文采用静态代码和动态debug实例分析,也为接下来分析更加复杂的创建方式打基础。

spring创建bean的方式

  1. 构造方法
    • 无参构造方法
    • 有参构造方法
  2. 工厂方法
    • 静态工厂方法
    • 实例工厂方法
  3. 实现FactoryBean接口
    接下来我们就开始分析无参构造方法创建bean这种方式

从单例bean创建入手

我们知道,在bean工厂加载完bean定义之后,会在AbstractApplicationContext的refresh()方法中完成对单例bean的提前创建,来看一下

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();
				
				//实例化所有剩余的非懒加载单例bean
				// Instantiate all remaining (non-lazy-init) singletons.	
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

就是在finishBeanFactoryInitialization(beanFactory);这个步骤,点进去看一下

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// Initialize conversion service for this context.
		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));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		// Allow for caching all bean definition metadata, not expecting further changes.
		beanFactory.freezeConfiguration();
		
		//实例化所有剩余非懒加载的单例bean
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

调用了beanFactory的preInstantiateSingletons方法
该方法在DefaultListableBeanFactory中的实现如下

@Override
	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		//获取bean工厂中所有bean定义名称
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		//依次对所有单例bean实例化、初始化
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			//是否单例bean判断
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//是否通过factoryBean方式创建bean
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				}
				//非factroyBean方式创建bean
				else {
					getBean(beanName);
				}
			}
		}

		//省略无关代码...
	}

代码中已经注释了主要环节的作用,我们来看关键的执行方法getBean();

getBean()方法解析

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

很简单,直接委托给doGetBean()方法。

doGetBean()方法解析

这个方法做了很多事,现在我们先将无关代码精简,直指真正创建bean的步骤,来看下精简后的代码

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		
		//转换得到beanName
		String beanName = transformedBeanName(name);
		Object bean;

		// 先检查单例缓存中时候有手工注册的单例bean
		Object sharedInstance = getSingleton(beanName);
		//
		if (sharedInstance != null && args == null) {			
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		
		//没有,走这里
		else {				
			try {		
				//创建单例bean
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				
				//创建原型bean
				else if (mbd.isPrototype()) {
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
				
				//创建其他类型bean,比如request、session
				else {
					String scopeName = mbd.getScope();		
					Scope scope = this.scopes.get(scopeName);					
					try {
						Object scopedInstance = scope.get(beanName, () -> {
							beforePrototypeCreation(beanName);
							try {
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
					catch (IllegalStateException ex) {
						...
					}
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		...
		//返回bean
		return (T) bean;
	}

可以看到,无论是单例bean、原型bean还是其他的request等范围bean,最终都是调用createBean(),看下这个方法。

createBean()方法解析

精简之后的核心代码如下

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		RootBeanDefinition mbdToUse = mbd;

		...
		
		// 给BeanPostProcessors一个返回代理而不是目标bean实例的机会
		// 其实就是创建aop代理类,这里我们先不作为主要分析对象
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
		
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);			
		return beanInstance;
				
	}

调用doCreateBean;,接着看

doCreateBean()方法解析

精简代码之后如下

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// 实例化bean
		BeanWrapper instanceWrapper = null;		
		instanceWrapper = createBeanInstance(beanName, mbd, args);
		
		Object bean = instanceWrapper.getWrappedInstance();		

		
		Object exposedObject = bean;
		//填充bean属性
		populateBean(beanName, mbd, instanceWrapper);
		//初始化bean
		exposedObject = initializeBean(beanName, exposedObject, mbd);
		

		return exposedObject;
	}

这里有3个关键方法,分别是
createBeanInstance():实例化bean
populateBean():填充bean属性
initializeBean():初始化bean
继续分析createBeanInstance()方法

createBeanInstance()方法解析

精简之后的核心代码如下

		Class<?> beanClass = resolveBeanClass(mbd, beanName);		
		
		//工厂方法方式创建bean
		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		//有参构造方法方式创建bean
		// Candidate constructors for autowiring?
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		//无参构造方法方式创建bean
		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);

核心方法有3个
instantiateUsingFactoryMethod():工厂方法方式创建bean
autowireConstructor():有参构造方法方式创建bean
instantiateBean():无参构造方法方式创建bean

来看instantiateBean()方法

instantiateBean()方法解析

精简代码后

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
		try {
			Object beanInstance;			
			beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
			
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {			
		}
	}

这里用了一个实例化策略类,直接看它的instantiate()方法

instantiate()方法解析

精简之后

@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		//不需要方法重写,就不需要cglib代理生成类,即默认的
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		//需要方法重写,就需要cglib动态代理生成类
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

这段代码比较简单,constructorToUse即为默认的无参构造函数,最终调用BeanUtils的instantiateClass方法反射生成bean,
来看下

instantiateClass()方法解析

精简之后代码如下

	Class<?>[] parameterTypes = ctor.getParameterTypes();
	Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
	Object[] argsWithDefaultValues = new Object[args.length];
	for (int i = 0 ; i < args.length; i++) {
		if (args[i] == null) {
			Class<?> parameterType = parameterTypes[i];
			argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
		}
		else {
			argsWithDefaultValues[i] = args[i];
		}
	}
	return ctor.newInstance(argsWithDefaultValues);

这里的代码也比较简单,就是反射创建实例bean,ctor.newInstance(argsWithDefaultValues),
至此,默认的无参构造方法创建bean方式结束。

总结

从以上分析的目录也可以看出,无参构造方法创建bean大致需要经过以下方法,
AbstractBeanFactory 的getBean()、doGetBean()
AbstractAutowireCapableBeanFactory 的createBean()、doCreateBean()、createBeanInstance()、instantiateBean()
SimpleInstantiationStrategy 的instantiate()
BeanUtils 的instantiateClass()
最终通过无参构造方法反射得到实例。

你可能感兴趣的:(源码,spring,java,spring)