5.x primavera trip Fuente trece finishBeanFactoryInitialization y getMergedLocalBeanDefinition
Completar la inicialización de BeanFactory
Como el análisis ya acabada invokeBeanFactoryPostProcessors
y 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 bean
creació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 bean
nombre, si no abstracta, instancia singleton de carga no perezoso, si es FactoryBean
, entonces adquirió FactoryBean
ejemplo, si se llega a este ejemplo, se determina si se debe de inmediato la carga FactoryBean
se crea ejemplo, el valor por defecto no se crea cuando sea necesario creado. Aquí hay que prestar atención a obtener FactoryBean
su nombre está beanName
precedido por &
el símbolo, si se adquiere FactoryBean
instancia se crea, es el nombre beanName
. Si no es FactoryBean
el tipo de ir directamente a la adquisición.
Después de que se complete la adquisición, todos los pacientes, sino también para un solo procesador, si es SmartInitializingSingleton
el tipo de conducta sobre afterSingletonsInstantiated
la 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 FactoryBean
clase UserDao
es una interfaz, UserDaoImple
que 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 - 获取testFactoryBean
a obtener es TestFactoryBean
la 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);
}
Prueba de dos - 获取&testFactoryBean
a llegar TestFactoryBean
en sí:
@Test
public void FactoryBeanTest() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(TestFactoryBean.class);
applicationContext.refresh();
Object obj= applicationContext.getBean("&testFactoryBean");
System.out.println(obj);
}
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 bean
definició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 bean
definido de tratar, ya que bean
la definición puede ser modificada , cuando se trata de la necesidad de manejar la última , es probable que tenga que modificar bean
la definición una vez más fusionado en un unificado RootBeanDefinition
. Debido a que BeanDefinition
hay 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 BeanDefinition
sub-categorías y crear uno nuevo RootBeanDefinition
con las propiedades de las profundidades copiar.
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. stale
Atributo 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=true
hace, es decir, la necesidad de consolidación, echamos un vistazo, primero AbstractBeanFactory
de clearMergedBeanDefinition
:
usó fue donde, en AbstractBeanFactory
el 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:
Otro lugar es invokeBeanFactoryPostProcessors
el último:
que BeanFactoryPostProcessor
el proceso Una vez finalizada, bean
la 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 spring
desea procesar bean
las definiciones pueden ser unificados, pero muchas bean
definiciones son diferentes clase de implementación subclases, y puede ser modificado procesador, por lo spring
que necesita para visitar bean
a 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.