欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

《spring设计思想》10-反射调用实现bean的实例化

程序员文章站 2022-05-23 15:18:41
...

上面一节简单的介绍了InstantiationAwareBeanPostProcessor可以在bean的实例化之前,调用回调的接口-postProcessorBeforInstantiation方法打断spring bean的默认实现。那本节简单的看下spring bean的默认实例化方法。

回到createBean(String beanName,RootBeanDefinition mbd,Objec[] args)方法。

	/**
	 * Central method of this class: creates a bean instance,
	 * populates the bean instance, applies post-processors, etc.
	 * @see #doCreateBean
	 */
	@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

	
		RootBeanDefinition mbdToUse = mbd;

		//beanClass : String -> Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
        // 仙履奇缘,给个机会
		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		// Spring bean的默认实例化方法
		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			
			return beanInstance;
		}

	}

继续跟踪方法调用 doCreateBean(beanName,mbdToUse,args);

	/**
	 * Actually create the specified bean. Pre-creation processing has already happened
	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
	 * <p>Differentiates between default bean instantiation, use of a
	 * factory method, and autowiring a constructor.
	 * @param beanName the name of the bean
	 * @param mbd the merged bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a new instance of the bean
	 * @throws BeanCreationException if the bean could not be created
	 * @see #instantiateBean
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 */
	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		final Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}
        //省略若干方法
        .......

	}

方法说明里讲:该方法是真正的创建bean的方法,仙履奇缘的故事已经发生过,大家啥也没发生,继续默认实现。

提炼出来一段代码 BeanWrapper instanceWrapper = createBeanInstance(beanName,mbd,args);

final Object bean = instanceWrapper.getWrappedInstance();

可以看到bean已经在createBeanInstance(beanName,mbd,args)方法中创建完成,继续追踪代码:

	/**
	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
	 * factory method, constructor autowiring, or simple instantiation.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @param args explicit arguments to use for constructor or factory method invocation
	 * @return a BeanWrapper for the new instance
	 * @see #obtainFromSupplier
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
        //最简单的bean的实例化代码
		// No special handling: simply use no-arg constructor.
		return instantiateBean(beanName, mbd);
	}

简单的看到,instantiateBean(beanName,mbd)方法实例化了bean

继续最终代码:beanInstance  = getInstantiationStrategy().instantiate(mbd,beanName,parent);

InstantiationStrategy接口定义了实例化bean的接口instantiate(mbd,beanName,parent);

默认实现 SimpleInstantiationStrategy:

方法实现:

Constructor<?> constructorToUse =  clazz.getDeclaredConstructor();
return BeanUtils.instantiateClass(constructorToUse);

继续看BeanUtils的方法instantiateClass(constrictorToUse);

            ReflectionUtils.makeAccessible(ctor);
			return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
					KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));

其实就是调用反射,使用Constructor.newInstance(args)方法获取实例化的bean。

调用堆栈:

《spring设计思想》10-反射调用实现bean的实例化