DefaultListableBeanFactory

DefaultListableBeanFactory is a complete, functionally mature IoC container. If your needs are simple, you can even use DefaultListableBeanFactory directly. If your needs are more complex, you can also achieve it by extending the functions of DefaultListableBeanFactory. It can be said that DefaultListableBeanFactory is the entire Spring IoC container. 's ancestor.

Create two new entity classes User and UserMessage classes and a configuration class MyConfig

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserMessage {

    private String phone;
    private String address;
}


@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
   private String username;

   @Autowired
   private UserMessage userMessage;
}


public class MyConfig {

    @Bean
    public User user(){
        return new User();
    }

    @Bean
    public UserMessage userMessage(){
        return new UserMessage("17860397188","123456");
    }
}

 Dynamically registering Bean, this is one of the functions of DefaultListableBeanFactory, but to be precise, it should be dynamically registering BeanDefinition.

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MyConfig.class).getBeanDefinition();
        beanFactory.registerBeanDefinition("config",beanDefinition);

        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory); //为beanfactory添加后处理器
        //beanfactory 后处理器解析@Bean等注解
        Map<String, BeanFactoryPostProcessor> beansOfType = beanFactory.getBeansOfType(BeanFactoryPostProcessor.class);
        beansOfType.values().forEach(i->i.postProcessBeanFactory(beanFactory));
        //Bean后处理器,针对Bean生命周期的各个阶段提供扩展,例如@Autowired
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().forEach(beanFactory::addBeanPostProcessor);

        Arrays.stream(beanFactory.getBeanDefinitionNames()).forEach(i-> System.out.println(i));
        User user = (User) beanFactory.getBean("user");
        System.out.println(user.getUserMessage());

Lazy loading of beans. At this time, the BeanDefinition is defined first, and the Bean will not be initialized until the Bean is actually called. There is also a preInstantiateSingletons method in DefaultListableBeanFactory that can register beans in advance. This method is declared in the ConfigurableListableBeanFactory interface. The DefaultListableBeanFactory class implements the ConfigurableListableBeanFactory interface and implements the methods in the interface.

@Override
public void preInstantiateSingletons() throws BeansException {
	if (logger.isTraceEnabled()) {
		logger.trace("Pre-instantiating singletons in " + this);
	}
	// Iterate over a copy to allow for init methods which in turn register new bean definitions.
	// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
	// Trigger initialization of all non-lazy singleton beans...
	for (String beanName : beanNames) {
		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
			if (isFactoryBean(beanName)) {
				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
				if (bean instanceof FactoryBean) {
					final 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);
					}
				}
			}
			else {
				getBean(beanName);
			}
		}
	}
	// Trigger post-initialization callback for all applicable beans...
	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();
			}
		}
	}
}

Guess you like

Origin blog.csdn.net/qq_43649937/article/details/134384786