当前位置: 首页 > news >正文

知识付费网站源码怪兽网站模板

知识付费网站源码,怪兽网站模板,免费微信公众号怎么创建,南京华夏天成建设有限公司网站WebServer 初始化过程在上一节中 Spring Boot 初始化了 WebServer 对应的工厂类。同时#xff0c;我们也知道对应 Web容器的WebServer实现类有:TomcatWebServer、JettyWebServer和UndertowWebServer。这节重点讲解这些 WebServer 是如何被初始化#xff0c;又如何启动的。Web…WebServer 初始化过程在上一节中 Spring Boot 初始化了 WebServer 对应的工厂类。同时我们也知道对应 Web容器的WebServer实现类有:TomcatWebServer、JettyWebServer和UndertowWebServer。这节重点讲解这些 WebServer 是如何被初始化又如何启动的。WebServer 接口的源代码如下。public interface WebServer {void start() throws WebServerException;void stop() throws WebServerException;int getPort();}接口定义了 3 个方法: start 方 法为启动容器stop 方 法为停止容器,getPort 方法为获得容器端口。现在以 Tomcat 的启动为例来说明整个内置容器的加载与启动。在上节中工厂类已经被自动配置初始化。那么在什么地方用到它们的呢?这要回到最初 Spring Boot 启动的过程中。还记得 SpringApplication 的 run 方法中有一个调用初始化容器的方法 refreshContext 吗?我们就从这个方法开始追踪。public ConfigurableApplicationContext run(String... args) {try {//初始化容器refreshContext(context);} catch (Throwable ex) {}在 run 方法中调用了 refreshContext 方法refreshContext 方法中又调用了refresh 方法。private void refreshContext(ConfigurableApplicationContext context) {//调用 refresh 方法refresh(context);refresh 方法的代码如下。protected void refresh(ApplicationContext applicationContext) {Assert. isInstanceOf(AbstractApplicat ionContext. class, applicationContext);((AbstractApplicationContext) applicationContext).refresh();}通过 refresh 方法我们能看到什么呢?对的就是 AbstractApplicationContext 这个抽象类该类的实例化对象在调用 refreshContext 方法之前已经通过 createApplicationContext 方法进行实例化了。createApplicationContext 方法的源代码如下。protected ConfigurableApplicat ionContext createApplicationContext() {//首先获取容器的类变量Class contextClass this . applicat ionContextClass;/如果为 null,则根据 web 应用类型按照默认类进行创建if (contextClass null) {trywitch (this . webApplicat ionType) {contextClass Class . forName(DEFAULT_ _SERVLET _WEB_ _CONTEXT_ CLASS);break;case REACTIVE:contextClass Class . forName (DEFAULT_ REACTIVE_ WEB_ CONTEXT_ CLASS);break;default:contextClass Class . forName (DEFAULT CONTEXT. CLASS);}catch (ClassNotFoundException ex) {如果存在对应的 Class 配置则通过 Spring 提 供的 BeanUtils 来进行实例化 return(ConfigurableApplicationContext) BeanUtils. instantiateClass(contextClass);}}}ServletWeb 项目默认会实例化 DEFAULT_ _SERVLET_ WEB_ _CONTEXT _CLASS 常量指定的 org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext 类。在 refresh 方法中调用的 AbstractApplicationContext 的 refresh 方法就是这个常量配置的类的 refresh 方法但 AnnotationConfigServletWebServerApplicationContext 方法内并没有该refresh 方法该方法定义在它的父类 ServletWebServerApplicationContext 中。Overridepublic final void refresh() throws BeansException, IllegalStateExceptiontry {super . refresh();} catch (RuntimeException ex) {stopAndReleaseWebServer();throw ex;}}ServletWebServerApplicationContext 的 refresh 方 法 仅 调 用 了 父 类AbstractApplication-Context 中的 refresh 方法。AbstractApplicationContext 中的 refresh方法的代码如下。Overridepublic void refresh() throws BeansException, IllegalStateException {synchronized (this . startupShutdownMonitor)try {...onRefresh();}catch (BeansException ex) {}忽略掉 refresh 方法中的其他方法我们重点了解下其调用的 onRefresh 方法。protected void onRefresh() throws BeansException {//为子类提供默认不做任何操作我们发现这个 onRefresh 方法默认是空的待其子类来实现。也就是说该方法真正的实现又回到了它的子类 ServletWebServerApplicationContext 中。Overrideprotected void onRefresh() {super . onRefresh();try {createWebServer();} catch (Throwable ex){throw new ApplicationContextException(Unable to start web server, ex);}经过一路的代码跟踪终于回到重点方法: createWebServer 方法。private void createWebServer() {WebServer webServer this . webServer;ServletContext servletContext getServletContext();if (webServer null servletContext null) {ServletwebServerFactory factory getWebServerFactory();this . webServer factory . getWebServer(getSelfInitializer());} else if (servletContext ! null) {initPropertySources();}}在 ServletWebServerApplicationContext 的 createWebServer 方 法 中 初 始 化 时 默 认web-Server 和 servletContext 都为 null,因此直接进入第一个 if 判断中的业务逻辑。看一下get-WebServerFactory 都做 了些什么。protected ServletWebServerFactory getWebServerFactory() {//使用 Bean name 数组的好处是可以不用考虑层级关系String[] beanNames getBeanF actory() . getBeanNamesForType(ServletWebServer-Factory.class);if (beanNames.length 0) {throw new ApplicationContextException(Unable to start ServletWebServe-rApplicationContext due to missing ServletWebServerFactory bean.);if (beanNames . length 1) {throw new ApplicationContextException(Unable to start ServletwebServer-ApplicationContext due to multiple” ServletWebServerFactory beans :”StringUtils.arrayToCommaDelimitedString(beanNames));}return getBeanFactory(). getBean(beanNames[0], ServletWebServerFactory.class);}getWebServerFactory 方法中通过 BeanFactory 获得类型为 ServletWebServerFactory 类的 beanNames 数组然后判断数组长度。当 beanNames 长度为 0 时说明容器中没有对应的 Bean 存在则抛出异常;当 beanNames 长度大于 1 时说明存在多个对应的 Bean,也就是说有可能同时存在多个 Web 容器的工厂方法同样抛出异常;只有 beanNames 长度等于 1 时说明恰好存在一个对应的 Bean, 才会获取对应的 Bean 并返回。如果一层层向上追溯 TomcatServletWebServerFactory 的类结构我们就会发现它先是继承了抽象类AbstractServletWebServerFactory,而抽象类AbstractServletWebServerFactory 又实现了口 ConfigurableServletWebServerFactory 接口ConfigurableServletWebServer-Factory又继承接口ServletWebServerFactory.这里获得的 ServletWebServerFactory 的具体实现类正是我们在上一节中通过自动配置实例化的TomcatServletWebServerFactory 对象的 Bean 名称。当获得 ServletWebServerFactory 之后便调用了它的 getWebServer 方法以 Tomcat 为例其实也就是调用了 TomcatServletWebServerFactory 的 getWebServer 方法。Overridepublic WebServer getWebServer(ServletContextInitializer... initializers)//内置 Tomcat 包中提供的类Tomcat tomcat new Tomcat();//获取并没置 baseDir 路径不存在则创建一个 ltomcat 为前缀的临时文件File baseDir (this. baseDirectory ! null) ? this. baseDirectorycreateTempDir(tomcat);tomcat . setBaseDir(baseDir . getAbsolutePath());/创建 ConnectorConnector connector new Connector(this . protocol);tomcat . getService(). addConnector(connector);// Connector 定制化customi zeConnector(connector);tomcat. setConnector( connector);tomcat. . getHost(). setAutoDeploy(false);configureEngine(tomcat. getEngine());for (Connector additionalConnector : this . additionalTomcatConnectors) {tomcat . getService() . addConnector ( additionalConnector);prepareContext(tomcat . getHost(), initializers);//创建 omcatWebServerreturn getTomcatwebServer(tomcat);}}TomcatServletWebServerFactory 的 getWebServer 方法中实现了 Tomcat 的创建、BaseDir的设置 、Connector 的初始化和定制化等一系 列初始化操作。至此上面代码中依旧没有 体现 TomcatServer 的创建和初始化 不要着急它们就在getWebServer 方法的最后- -行代码调用的 getTomcatWebServer 方法中。protected TomcatWebServer getTomcatWebServer (Tomcat tomcat) {return new TomcatWebServer(tomcat, getPort() getTomcatWebServer 方法的实现很简单将 getWebServer 中创建的 Tomcat 对象和当前类中 port 值是否大于等于 0 的判断结果作为 TomcatWebServer 构造方法的参数传入创建 TomcatWebServer 对象。针 对 getTomcatWebServer 方 法 子 类 可 以 重 写 该 方 法 返 回 一 个 不 同 的Tomcat-WebServer 或者添加针对 Tomcat Server 的一些额外操作。先看 TomcatWebServer 的构造方法源码。public class TomcatWebServer implements WebServer {private final Tomcat tomcat;private final boolean autoStart;public TomcatWebServer(Tomcat tomcat, boolean autoStart) {Assert . notNull(tomcat, Tomcat Server must not be null);this. tomcat tomcat;this. autoStart autoStart;initialize();}}构造方法接收 Tomcat tomcat 和 boolean autoStart 两个参数并将其赋值给对应的成员变量。其中 Tomcat 参数不能为 null, autoStart 参 数则根据端口是否大于等于 0 来决定是否启动服务。在构造方法的最后调用了 nitialize 方法来进行初始化操作。omcatWebServern 的 initialize 方法源代码如下。public class TomcatWebServer implements WebServer {private final Tomcat tomcat;private final boolean autoStart;privatevolatile boolean started;logger. info(Tomcat initialized with port(s): ” getPortsDescription(fsynchronized (this .monitor) {// 将 实 例 id 添 加 到 tomcat 引 擎 名 字 中 格 式 为 “ 原 引 / 擎 名 字 实 例 id”ContextcontextfindContext()://添加生命周期的监昕事件context . addL ifecyclelistener((event) - {if (context . equals(event. getSource()) Lifecycle . START EVENT.equals(event . getType()))//移除 connector, 磅保当服务器启动时不会进行协议绑定})//启动服务触发初始化监听this. tomcat . start();/可以直接在主线程中重新抛出失败异常 TomcatStarter 不存在或状态错误均会抛出异常rethrowDeferredStartupExceptions();try/绑定一个命名的 context.到类加载器(), getClass().getClassLoader());sLoader(context, context. getNamingTokencatch (NamingException ex)// 当命名不可用时(抛异常) 直接跳过并继续// 与 Jetty 不同 所有 Tomcat 线程都是守护程序线程。创建一 一个阻止非守护程序止立即关闭startDaemonAwaitThread();} catch (Exception ex) {stopSilently();destroySilently();throw new WebServerException(Unable to start embedded Tomcat, e x)}}}}通过以上源代码可以看出在 TomcatWebServer 的 initialize 方法中做了以下操作:重命名tomcat 弓|擎名称、对 Context 添加生 命周期监听事件、启动服务触发初始化监听、检查TomcatStarter 对象是否存在及 Container 状态是否正确、绑定命名到类加载器、启动守护等待线程等。至此针对 Tomcat 的 TomcatWebServer 的初始化已经完成。关于其他 Web 容器的WebServer 初始化操作读者可仿照本节的思路进行源代码分析这里不再逐一讲解。本文给大家讲解的内容是SpringBoot内置Servlet容器源码解析WebServer初始化过程下篇文章给大家讲解的是DispatcherServlet的加载过程觉得文章不错的朋友可以转发此文关注小编感谢大家的支持
http://www.pierceye.com/news/162429/

相关文章:

  • 线上设计师网站网络维护是什么意思
  • 培训网站建设阿里云如何建设网站
  • 手机网站列表模板做一钓鱼网站吗
  • 太原网站建设方案策划请问有重庆有做网站吗
  • 网站备案购买语音网站怎么做
  • ftp上传文件到网站深圳成品网站超市
  • 网站开发时app打开很慢建设网站还要云服务器吗
  • 网站设计方案应该怎么做网站自适应开发
  • 徐州手机网站设计青龙县建设局网站
  • 罗湖网站建设费用帮忙做文档的网站
  • 如何在720云网站做全景视频域名注册网站查询工具
  • 网站定制开发流程和功能wordpress怎么看访问
  • 浙江省互联网建设网站python开发手机网站开发
  • 做网站需要多少钱一年动漫制作技术是学什么
  • 刘洋网站建设 够完美保卫处网站建设
  • 个人怎么申请营业执照北京朝阳区优化
  • 免费的舆情网站不用下载直接打开江西城乡建设网站
  • 那些网站是做金融行业网站主目录权限配置
  • 本地网站做不大wordpress 安全设置
  • 宁波教育平台网站建设广告行业怎么找客户
  • php企业网站开发实验总结商城网站建设模板
  • 单词优化和整站优化建设银行的网站特点
  • 厦门淘宝网站设计公司wordpress大前端dux5.2
  • 淮南网站seo网络信息发布平台
  • 网站自己做流量如何查询网站被百度收录情况
  • 网络营销网站源码做网站中怎么设置单张图片
  • 怎么做淘宝客网站网站定位代码
  • 自己给网站做logo卓成建设集团有限公司网站
  • 西宁建设网站软件徐州集团网站建设公司
  • 做网站卖设备找哪家好百度智能云windows系统服务器建站