springBoot容器刷新
上篇说了启动过程,现在说其中的刷新。上代码
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//刷新前准备
prepareRefresh();
//获取工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//工厂预处理(给工厂设置一些必要参数 类加载器 后置处理等)
prepareBeanFactory(beanFactory);
try {
//工厂后置处理
postProcessBeanFactory(beanFactory);
//执行beanFactory后置处理器
invokeBeanFactoryPostProcessors(beanFactory);
//注册bean后置处理器
registerBeanPostProcessors(beanFactory);
//初始化信息(国际化等)
initMessageSource();
//初始化应用事件派发器
initApplicationEventMulticaster();
//子类实现(web容器就是在这里加载的)
onRefresh();
//注册监听器
registerListeners();
// 实例化剩下的bean(单例)
finishBeanFactoryInitialization(beanFactory);
// 后续操作(初始化生命周期等)
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();
}
}
}
prepareRefresh
protected void prepareRefresh() {
//记录时间,设置状态
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// 初始化属性源信息
initPropertySources();
//验证环境属性信息
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
}
invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//获取所有实现了BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的类然后执行 postProcessBeanFactory方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
点进去invokeBeanFactoryPostProcessors
首先找到实现了BeanDefinitionRegistryPostProcessor接口和BeanFactoryPostProcessor接口的所有类,根据是否实现三种排序接口分类处理排序,放到一个集合中
image.png然后执行方法,其中第二个实例是自定义实例
image.png自定义实例如下 :实现BeanDefinitionRegistryPostProcessor
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("postProcessBeanDefinitionRegistry数量。。。"+registry.getBeanDefinitionCount());
// System.out.println("postProcessBeanDefinitionRegistry数量。。。"+registry.getBeanDefinitionCount());
RootBeanDefinition beanDefinition = new RootBeanDefinition(Row.class);
registry.registerBeanDefinition("row",beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("postProcessBeanFactory数量"+beanFactory.getBeanDefinitionCount());
}
}
此外其中一个重要的PostProcessor ConfigurationClassPostProcessor,它会对项目中的@Configuration注解修饰的类(@Component、@ComponentScan、@Import、@ImportResource修饰的类也会被处理)进行解析,解析完成之后把这些bean注册到BeanFactory中。需要注意的是这个时候注册进来的bean还没有实例化
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
registerBeanPostProcessors
和beanFactory的后置处理器一样,找到三种排序实现类进行注册实例化,这些BeanPostProcessor包括有AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)、RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)、CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。如果是自定义的BeanPostProcessor,已经被ConfigurationClassPostProcessor注册到容器内。这些BeanPostProcessor会在这个方法内被实例化(通过调用BeanFactory的getBean方法,如果没有找到实例化的类,就会去实例化)。
onRefresh
servlet容器就是在这里加载的,点进去找到子类ServletWebServerApplicationContext
@Override
protected void onRefresh() {
super.onRefresh();
try {
createWebServer();
}
catch (Throwable ex) {
throw new ApplicationContextException("Unable to start web server", ex);
}
}
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
ServletWebServerFactory factory = getWebServerFactory();
//创建一个server
this.webServer = factory.getWebServer(getSelfInitializer());
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context",
ex);
}
}
initPropertySources();
}
创建server有三个子类,也是springBoot支持的三种servlet容器
image.png进到tomcat里,看到了tomcat熟悉的一些组件
public WebServer getWebServer(ServletContextInitializer... initializers) {
Tomcat tomcat = new Tomcat();
File baseDir = (this.baseDirectory != null) ? this.baseDirectory
: createTempDir("tomcat");
tomcat.setBaseDir(baseDir.getAbsolutePath());
//连接器
Connector connector = new Connector(this.protocol);
//service
tomcat.getService().addConnector(connector);
customizeConnector(connector);
tomcat.setConnector(connector);
//host
tomcat.getHost().setAutoDeploy(false);
configureEngine(tomcat.getEngine());
for (Connector additionalConnector : this.additionalTomcatConnectors) {
tomcat.getService().addConnector(additionalConnector);
}
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}
finishBeanFactoryInitialization
开始实例化容器中的bean(后面详细说 bean的创建过程)
网友评论