SpringBoot中使用的ApplicationContext主要是ConfigurableApplicationContext这个接口。
1、接口继承了ApplicationContext->ListableBeanFactory->BeanFactory。所以ConfigurableApplicationContext也是一个BeanFactory类,拥有getBean()方法用来获取Spring管理的Bean对象。
2、接口定义了一个很重要的方法refresh()
/** * Load or refresh the persistent representation of the configuration, * which might an XML file, properties file, or relational database schema. * <p>As this is a startup method, it should destroy already created singletons * if it fails, to avoid dangling resources. In other words, after invocation * of that method, either all or no singletons at all should be instantiated. * @throws BeansException if the bean factory could not be initialized * @throws IllegalStateException if already initialized and multiple refresh * attempts are not supported */ void refresh() throws BeansException, IllegalStateException;
通过注释可以得知:这个方法用于加载或者刷新配置,配置可以是一个xml文件,配置文件等各种形式。我们也知道,Spring管理的各种Bean我们可以通过注解或者xml的形式进行配置,即我们可以认为这个方法主要是用于加载我们委托Spring进行管理的各种Bean。
接口有了,我们来看看实现,ConfigurableApplicationContext的主要实现位于实现了它的抽象类AbstractApplicationContext
1、对于getBean()方法的实现,其实应该说对于整个BeanFactory接口的实现,AbstractApplicationContext都是直接通过获取一个BeanFactory,之后代理这个BeanFactory来实现的。获取BeanFactory使用的是getBeanFactory()这个方法,这个方法是一个抽象方法,留给子类实现,见GenericApplicationContext
@Override public Object getBean(String name) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name, requiredType); } @Override public Object getBean(String name, Object... args) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name, args); } @Override public <T> T getBean(Class<T> requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(requiredType); } @Override public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(requiredType, args); }
2、refresh()方法的实现
@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(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } }
可以看到方法做了很多很多的操作,具体操作及解析参考注释及对应连接(todo)