5.x primavera trip Fuente trece finishBeanFactoryInitialization y getMergedLocalBeanDefinition

Completar la inicialización de BeanFactory

Como el análisis ya acabada invokeBeanFactoryPostProcessorsy registerBeanPostProcessors, a continuación, en el medio de algunos del núcleo no es el salto, la última pieza restante del núcleo, hay un solo ejemplo de la beancreación, y también los lugares más centrales, lo analizamos lentamente, se omite código no subyacente, de hecho, sólo un código.

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		...
		//准备实例化单例
		// Instantiate all remaining (non-lazy-init) singletons.
		beanFactory.preInstantiateSingletons();
	}

DefaultListableBeanFactory 的 preInstantiateSingletons

En primer lugar obtendrá beanDefinitionNames, y luego crear una copia, hay un cambio en el tiempo para evitar el uso de. Luego travesía beannombre, si no abstracta, instancia singleton de carga no perezoso, si es FactoryBean, entonces adquirió FactoryBeanejemplo, si se llega a este ejemplo, se determina si se debe de inmediato la carga FactoryBeanse crea ejemplo, el valor por defecto no se crea cuando sea necesario creado. Aquí hay que prestar atención a obtener FactoryBeansu nombre está beanNameprecedido por &el símbolo, si se adquiere FactoryBeaninstancia se crea, es el nombre beanName. Si no es FactoryBeanel tipo de ir directamente a la adquisición.
Aquí Insertar imagen Descripción
Después de que se complete la adquisición, todos los pacientes, sino también para un solo procesador, si es SmartInitializingSingletonel tipo de conducta sobre afterSingletonsInstantiatedla llamada.

@Override
	public void preInstantiateSingletons() throws BeansException {
		...
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);//创建一个副本,让原始的还能继续注册bean定义
		//触发非懒加载的单例bean初始化
		for (String beanName : beanNames) {
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);//合并父类的bean定义
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {//非抽象,单例,非懒加载
				if (isFactoryBean(beanName)) {//是否是FactoryBean类型的,是的话要加前缀获取
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);//获取FactoryBean
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;//是否需要立即创建FactoryBean中的bean
						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);
						}
					}
				}
				else {//非FactoryBean
					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((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

ejemplos prácticos FactoryBean

Creación de una FactoryBeanclase UserDaoes una interfaz, UserDaoImpleque es la clase de implementación.

@Component
public class TestFactoryBean implements FactoryBean<UserDao> {
	@Override
	public UserDao getObject() throws Exception {
		return new UserDaoImple();
	}

	@Override
	public Class<?> getObjectType() {
		return UserDao.class;
	}
}

Una prueba - 获取testFactoryBeana obtener es TestFactoryBeanla getObject()instancia creada:

 @Test
    public void FactoryBeanTest() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(TestFactoryBean.class);
        applicationContext.refresh();
        Object obj=  applicationContext.getBean("testFactoryBean");
        System.out.println(obj);
    }

Aquí Insertar imagen Descripción
Prueba de dos - 获取&testFactoryBeana llegar TestFactoryBeanen sí:

 @Test
    public void FactoryBeanTest() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(TestFactoryBean.class);
        applicationContext.refresh();
        Object obj=  applicationContext.getBean("&testFactoryBean");
        System.out.println(obj);
    }

Aquí Insertar imagen Descripción

getMergedLocalBeanDefinition definición grano de fusión

De hecho, esta muy temprano, la parte delantera no dijo, ahora parecen ser más apropiado. ¿Por qué no tener una beandefinición de lo que, creo que esto puede ser el fin de proceso de unificar , muchos lugares se adquieren después de la fusión beandefinido de tratar, ya que beanla definición puede ser modificada , cuando se trata de la necesidad de manejar la última , es probable que tenga que modificar beanla definición una vez más fusionado en un unificado RootBeanDefinition. Debido a que BeanDefinitionhay diferentes clases de implementación, pero hay sin duda será una subclase más completa es RootBeanDefinition, sino que también proporciona un constructor y un método de copia de clonación profunda, se puede pasar a otros BeanDefinitionsub-categorías y crear uno nuevo RootBeanDefinitioncon las propiedades de las profundidades copiar.
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
Echemos un vistazo al código fuente de este método, a partir de la definición de la fusión por absorción, si lo encuentra, y no es necesario fusionar el retorno directo, de lo contrario fusionar. staleAtributo indica si o no a la fusión, se necesita el valor predeterminado.

	protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
		// Quick check on the concurrent map first, with minimal locking.
		RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
		if (mbd != null && !mbd.stale) {//存在且不需要合并的话就直接返回
			return mbd;
		}
		return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
	}

¿Cuándo hay que configurar a fusionar

Cuando se stale=truehace, es decir, la necesidad de consolidación, echamos un vistazo, primero AbstractBeanFactoryde clearMergedBeanDefinition:
Aquí Insertar imagen Descripción
usó fue donde, en AbstractBeanFactoryel markBeanAsCreated, y dijo que los comentarios aquí, le permitió fusionar porque estamos unidos procesamiento, se combinan para determinar que, por lo que en este momento se va a crear, puede necesitar las últimas definiciones de frijol, por lo fusionar una vez, para obtener la última definición de frijol:
Aquí Insertar imagen Descripción
Otro lugar es invokeBeanFactoryPostProcessorsel último:
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
Aquí Insertar imagen Descripción
que BeanFactoryPostProcessorel proceso Una vez finalizada, beanla definición puede cambiar, por lo que necesito para fusionar con el fin de garantizar que la fusión es la última .

resumen de combinación

¿Por qué se resumen en virtud de la fusión significa simplemente que springdesea procesar beanlas definiciones pueden ser unificados, pero muchas beandefiniciones son diferentes clase de implementación subclases, y puede ser modificado procesador, por lo springque necesita para visitar beana la fusión cuando se define, por un lado, la última fusión definición, una lata en el centro, de hecho, es mi conjetura.

Comentario tanto, parece decir algunas de amplificación, ah vergüenza, pero eso está bien, se puede entender muy bien, no yo también escribí blanco, la próxima vez que continuarla.

Pues bien, hoy aquí, esperamos estudio ayuda y entender, no rocíe el Gran Dios ver, comprender solamente su propio aprendizaje, capacidad limitada, por favor excusa.

Publicados 235 artículos originales · ganado elogios 74 · Vistas a 30000 +

Supongo que te gusta

Origin blog.csdn.net/wangwei19871103/article/details/105014627
Recomendado
Clasificación