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

宁波建站模板源码深圳网站优化费用

宁波建站模板源码,深圳网站优化费用,网站新闻详细页面设计,遵义市住房和城乡建设局官方网站6tomcat 介绍 tomcat 是 web容器#xff08;servlet 容器#xff09;#xff0c;不管请求是访问静态资源HTML、JSP还是java接口#xff0c;对tomcat而言#xff0c;都是通过servlet访问#xff1a; 访问静态资源#xff0c;tomcat 会交由一个叫做DefaultServlet的类来处…tomcat 介绍 tomcat 是 web容器servlet 容器不管请求是访问静态资源HTML、JSP还是java接口对tomcat而言都是通过servlet访问 访问静态资源tomcat 会交由一个叫做DefaultServlet的类来处理。访问 JSPtomcat 会交由一个叫做JspServlet的类来处理。访问 Servlet tomcat 会交由一个叫做 InvokerServlet的类来处理。 所谓 jsp 就是 html 加上 java 代码片段JspServlet 最终输出的也是 html 而已。 tomcat 启动 spring 项目 了解 springboot 内嵌 tomcat 启动原理之前应该了解“祖先” spring 怎么启动和加载上下文的对 springboot 的理解才深刻。 web.xml配置 spring 启动必须依赖 web 容器这里以 tomcat 举例。 spring 项目中简单的 web 配置如下 ?xml version1.0 encodingUTF-8? web-app listener listener-classorg.springframework.web.context.ContextLoaderListener/listener-class /listener context-param param-namecontextConfigLocation/param-name param-value/WEB-INF/root-context.xml/param-value /context-param servlet servlet-nameapp1/servlet-name servlet-classorg.springframework.web.servlet.DispatcherServlet/servlet-class init-param param-namecontextConfigLocation/param-name param-value/WEB-INF/app1-context.xml/param-value /init-param load-on-startup1/load-on-startup /servlet servlet-mapping servlet-nameapp1/servlet-name url-pattern/app1/*/url-pattern /servlet-mapping /web-appspring 怎么启动 tomcat 通过调用 spring 中的 servlet 对象DispatcherServlet然后调用该对象的 init() 方法作为入口启动spring。 如何调用到 spring 中的 servlet 对象分为以下两种 web.xml 配置文件方式tomcat 通过 web.xml 配置文件中 servlet 标签指定的 servlet 类路径反射生成 servlet 对象。java config 方式没有 web.xml 配置文件了项目中必须实现 WebApplicationInitializer 接口并现实 WebApplicationInitializer 的 onStartup 方法在 onStartup 方法中创建 dispacherServlet 并指定使用。 上述 java config 方式衍生出另一个问题WebApplicationInitializer 的实现类怎么被 tomcat 调用到呢 HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer {Overridepublic void onStartup(Nullable SetClass? webAppInitializerClasses, ServletContext servletContext)throws ServletException {......} }tomcat 会通过SPI机制找到 ServletContainerInitializer 接口的所有实现类然后反射生成对象并轮流执行实现类中 onStartup 方法。SpringServletContainerInitializer 就是 ServletContainerInitializer 实现类之一。SpringServletContainerInitializer 类上有HandlesTypes({WebApplicationInitializer.class})注释这个注释是 servlet 规范中的tomcat 会通过字节码加载技术ASM找到注解中指定类及子类WebApplicationInitializer.class 及子类然后将其作为参数传给 SpringServletContainerInitializer 的 onStartup方法使用。我们自定义的WebApplicationInitializer 实现类就这样被调用到了 。 所以我们实现了 WebApplicationInitializer 接口就会被 tomcat 加载。 怎么加载 springContext? tomcat 通过调用 DispatcherServlet 对象的 init() 方法加载 springContext 上下文所以 DispatcherServlet 对象内有一个字段存放 springContext。 若配置多个 servletspringContext 有几个 每个 servlet 创建过程中都会创建 springcontext各 servlet 都有自己的上下文。所以各 servlet 的 init-param 标签中指定的扫描路径如果有重复的重复的 bean 对象也会在各 servlet 的 springcontext 中新建不会共用。那么重复的 bean 对象是不是有点浪费内存呢确实如此所以在多个servlet的情况下需要配 listener 标签表示配置父容器root context。可以合理配置父容器加载 service 和 repository 层的 bean这部分可以共用而 controller 层的 bean 是在各 servlet 中的子容器中加载因为涉及到servlet路由嘛。 不过一般都不会有多个servlet通常常规项目中 web.xml 中 listener 标签根本就不需要配置。 springboot 启动 tomcat 启动 web 容器 上述说的 spring 启动必须依赖 web 容器启动。由 web 容器通过 SPI 机制加载 spring 自己的 servlet DispatcherServlet再通过 servlet 对象创建 springContext。 而 springboot 不需要外部 web 容器了那它怎么监听端口接收请求呢难道 springboot 内部又重新写了一个 servlet当然不是看下面代码 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.// 同时会创建 web 容器。onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();}......}...... }上述代码片很熟悉吧如果不熟的查查spring初始化context流程这里不做详细描述。 主要看 onRefresh() 方法该方法启动容器的流程大概如下以 tomcat 为例 onRefresh() 方法内会调用 createWebServer() 方法createWebServer() 方法内会调用 tomcat||jetty||undertow jar 包依赖提供的方法来创建 web 容器并启动。比如 tomcat它是这样创建new Tomcat()。创建容器后对 tomcat 容器的Connector进行配置并将 DispatcherServlet 添加到 tomcat 容器中。最后 tomcat.start() 启动容器。 tomcat\jetty\undertow springboot用哪个 我们了解到了 springboot 会调用 createWebServer() 方法创建“合适”的 web 容器。 那 springboot 怎么判断该创建 tomcat、jetty 还是 undertow 容器呢 实际上就是在 createWebServer() 方法里面判断的该方法代码如下 private void createWebServer() {WebServer webServer this.webServer;ServletContext servletContext getServletContext();if (webServer null servletContext null) {// 选择用哪个容器ServletWebServerFactory factory getWebServerFactory();// 创建及启动 web 容器this.webServer factory.getWebServer(getSelfInitializer());getBeanFactory().registerSingleton(webServerGracefulShutdown,new WebServerGracefulShutdownLifecycle(this.webServer));getBeanFactory().registerSingleton(webServerStartStop,new WebServerStartStopLifecycle(this, this.webServer));}else if (servletContext ! null) {try {getSelfInitializer().onStartup(servletContext);}catch (ServletException ex) {throw new ApplicationContextException(Cannot initialize servlet context, ex);}}initPropertySources(); }上述代码片getWebServerFactory() 方法会获得 tomcat||jetty||undertow 的 ServletWebServerFactory 用这个 factory 对象就能创建对应的 web 容器。 而在 getWebServerFactory() 方法内是按类型从 SpringContext 中获取 ServletWebServerFactory 类型的 bean。 所以只要 SpringContext 注入什么容器的 ServletWebServerFactoryspringboot 就会启动什么容器。 什么地方注入 ServletWebServerFactory 呢 在 ServletWebServerFactoryConfiguration 这个配置类将tomcat||jetty||undertow的 ServletWebServerFactory 注入进 springContext配置类伪代码如下 Configuration(proxyBeanMethods false) class ServletWebServerFactoryConfiguration { // tomcat 的 factoryConfiguration(proxyBeanMethods false)ConditionalOnClass({ Servlet.class, Tomcat.class, UpgradeProtocol.class })ConditionalOnMissingBean(value ServletWebServerFactory.class, search SearchStrategy.CURRENT)static class EmbeddedTomcat {BeanTomcatServletWebServerFactory tomcatServletWebServerFactory( ... ) { TomcatServletWebServerFactory factory new TomcatServletWebServerFactory();... return factory;}}// Jetty 的 factoryConfiguration(proxyBeanMethods false)ConditionalOnClass({ Servlet.class, Server.class, Loader.class, WebAppContext.class })ConditionalOnMissingBean(value ServletWebServerFactory.class, search SearchStrategy.CURRENT)static class EmbeddedJetty {BeanJettyServletWebServerFactory JettyServletWebServerFactory( ... ) { JettyServletWebServerFactory factory new JettyServletWebServerFactory();... return factory;}}// Undertow 的 factory....... }可以看出只要引入了某 web 容器的依赖对应的 ConditionalOnClass 就能满足该 web 容器的 ServletWebServerFactory 就会被注入进 springboot。 那项目如果引入了多个 web 容器依赖springboot 使用哪一个 还想使用哪个getWebServerFactory() 方法内就直接报错了Unable to start ServletWebServerApplicationContext due to multiple ServletWebServerFactory beans : xxx。 我们平时使用 tomcat 那 jetty、undertow 等容器依赖便不会引入。那上述 ServletWebServerFactoryConfiguration 类的代码ConditionalOnClass 中某些类肯定找不到运行时不会报错吗 首先应该知道 spring 怎么判断是否是 bean 对象常人理解 spring 是通过 JVM 反射获取类注解信息来确定是否反射生成 bean 对象注入 SpringContext 中。 但实际 spring 并不是这样判断的如果通过 JVM 获取类信息那不是启动前要把所有类都加载一次这和 JVM 用时加载的思想冲突了。所以spring 是通过 ASM 技术从 class 字节码文件中获取注解信息来判断是否是需要的 bean。 之所以没有依赖也不会报错是因为spring 会通过 ASM 技术取出 ConditionalOnClass 注解中所有的 values后会用 ClassLoader 尝试加载这些 values如果加载不到catch住异常使其不会报错同时这个类也被认为不符合注入条件不会生成对象注入 springcontext。所以没引入所有 web 容器依赖也不会报错。
http://www.w-s-a.com/news/938828/

相关文章:

  • 成都网站优化公司哪家好网站建设帮助中心
  • 做外单什么网站好佛山市建设企业网站服务机构
  • 哪些网站是单页面应用程序北京门头沟山洪暴发
  • 织梦(dedecms)怎么修改后台网站默认"织梦内容管理系统"标题关键词优化收费标准
  • 网站设计和备案企业官网网站建设免费
  • 公司概况-环保公司网站模板搜索引擎营销的基本流程
  • 门户网站建设经验天津市建设银行租房网站
  • 百度推广 帮做网站吗怎样修改网站的主页内容
  • 网站怎么做dns解析公司官网改版方案
  • 湛江市住房和城乡建设局网站杭州网站公司哪家服务好
  • 设计网站公司湖南岚鸿设计镜像的网站怎么做排名
  • 你注册过哪些网站微信app下载安装官方版2019
  • 杭州滨江的网站建设公司人才招聘网网站策划方案
  • 门户网站是指提供什么的网站网站优化需要工具
  • 和小男生做的网站代理公司注册步骤
  • 天猫网站建设的目标是什么seo有些什么关键词
  • 网站前端建设都需要什么莱芜信息港网页
  • 如何做360网站优化网站建设培训教程新手入门到精通
  • 做网站有的浏览器怎么做网站网站赚钱
  • 织梦 做网站 教程百度登录个人中心官网
  • ftp怎么修改网站wordpress分享积分
  • 营销策划方案的步骤西安关键词优化软件
  • 南宁自己的网站移动互联网技术学什么
  • 2017湖北建设教育协会网站自己接单做网站
  • 定制网站建设制作h5网站要多久
  • 泰安中呼网站建设有限公司 概况个人网站的设计与实现参考文献
  • 圣诞节网站怎么做怎么获取网站的图片
  • 想找个人做网站音乐网站建设教程视频教程
  • 网站收录一键提交阿里巴巴做网站多少钱
  • 怎么做网站投放广告商务网站建设实训报告