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

百度站长平台官网死链提交怎样做公司网站推广

百度站长平台官网死链提交,怎样做公司网站推广,做宠物网站还有前景嘛,网页首页设计模板图片tomcat 介绍 tomcat 是 web容器(servlet 容器),不管请求是访问静态资源HTML、JSP还是java接口,对tomcat而言,都是通过servlet访问: 访问静态资源,tomcat 会交由一个叫做DefaultServlet的类来处…

tomcat 介绍

tomcat 是 web容器(servlet 容器),不管请求是访问静态资源HTML、JSP还是java接口,对tomcat而言,都是通过servlet访问:

  • 访问静态资源,tomcat 会交由一个叫做DefaultServlet的类来处理。
  • 访问 JSP,tomcat 会交由一个叫做JspServlet的类来处理。
  • 访问 Servlet ,tomcat 会交由一个叫做 InvokerServlet的类来处理。

所谓 jsp 就是 html 加上 java 代码片段,JspServlet 最终输出的也是 html 而已。

tomcat 启动 spring 项目

了解 springboot 内嵌 tomcat 启动原理之前,应该了解“祖先” spring 怎么启动和加载上下文的,对 springboot 的理解才深刻。

web.xml配置

spring 启动必须依赖 web 容器,这里以 tomcat 举例。

spring 项目中简单的 web 配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/root-context.xml</param-value> </context-param> <servlet> <servlet-name>app1</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/app1-context.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>app1</servlet-name> <url-pattern>/app1/*</url-pattern> </servlet-mapping> 
</web-app>

spring 怎么启动?

tomcat 通过调用 spring 中的 servlet 对象(DispatcherServlet),然后调用该对象的 init() 方法,作为入口启动spring。

如何调用到 spring 中的 servlet 对象,分为以下两种:

  • web.xml 配置文件方式:tomcat 通过 web.xml 配置文件中 servlet 标签指定的 servlet 类路径,反射生成 servlet 对象。
  • java config 方式:没有 web.xml 配置文件了,项目中必须实现 WebApplicationInitializer 接口,并现实 WebApplicationInitializeronStartup 方法,在 onStartup 方法中创建 dispacherServlet 并指定使用。

上述 java config 方式衍生出另一个问题:WebApplicationInitializer 的实现类怎么被 tomcat 调用到呢?

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {@Overridepublic void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)throws ServletException {......}
}
  • tomcat 会通过SPI机制,找到 ServletContainerInitializer 接口的所有实现类,然后反射生成对象,并轮流执行实现类中 onStartup 方法。SpringServletContainerInitializer 就是 ServletContainerInitializer 实现类之一。
  • SpringServletContainerInitializer 类上有@HandlesTypes({WebApplicationInitializer.class})注释,这个注释是 servlet 规范中的,tomcat 会通过字节码加载技术(ASM),找到注解中指定类及子类(WebApplicationInitializer.class 及子类),然后将其作为参数传给 SpringServletContainerInitializeronStartup方法使用。我们自定义的WebApplicationInitializer 实现类就这样被调用到了 。

所以我们实现了 WebApplicationInitializer 接口,就会被 tomcat 加载。

怎么加载 springContext?

tomcat 通过调用 DispatcherServlet 对象的 init() 方法,加载 springContext 上下文,所以 DispatcherServlet 对象内有一个字段存放 springContext。

若配置多个 servlet,springContext 有几个?

  • 每个 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||undertowServletWebServerFactory, 用这个 factory 对象就能创建对应的 web 容器。

而在 getWebServerFactory() 方法内是按类型从 SpringContext 中获取 ServletWebServerFactory 类型的 bean。

所以只要 SpringContext 注入什么容器的 ServletWebServerFactory,springboot 就会启动什么容器。

  • 什么地方注入 ServletWebServerFactory 呢?

ServletWebServerFactoryConfiguration 这个配置类,将tomcat||jetty||undertowServletWebServerFactory 注入进 springContext,配置类伪代码如下:

@Configuration(proxyBeanMethods = false)
class ServletWebServerFactoryConfiguration {   // tomcat 的 factory@Configuration(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 的 factory@Configuration(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.ds6.com.cn/news/115770.html

相关文章:

  • 推广游戏赚钱的平台长沙seo行者seo09
  • 怎么做网站的banner百度软文推广怎样收费
  • 做网站客户尾款老不给怎么办怎么在百度上做推广上首页
  • thinkphp做网站后台怎么样在百度上推广自己的产品
  • 网站登录接口怎么做seo网站优化培训多少价格
  • 西安企业网站河北百度seo
  • 沧州网站建设开发服务手机百度经验首页登录官网
  • 广告制作流程步骤百度seo怎么做网站内容优化
  • 大良招聘网站建设上海百度seo优化
  • 龙岩找工作网站唐山建站公司模板
  • 广州建设大马路小学网站现在做百度快速收录的方法
  • 做网站的名字大全衡阳seo排名
  • 高端网站建设上海济南百度推广代理商
  • 购物网站建设渠道软文免费发布平台
  • 高端网站开发案例展示推广关键词排名查询
  • 淄博桓台网站建设公司线上推广有哪些
  • 商旅网站制作百度seo排名点击器app
  • 郴州市住房和城乡建设局网站seo数据优化
  • 手机制作网页app上海seo外包
  • 政府力推企业做网站设计本网站
  • 公司介绍ppt制作模板北京seo主管
  • 做学校后台网站用什么浏览器2345网址导航怎么下载
  • wordpress中文标题404湖南网络优化
  • h5网站怎么做的西安网站优化推广方案
  • 网站备案个人使用数据查询网站
  • 顺德高端网站建设百度信息流怎么投放
  • 永州建设学校官方网站百度指数批量获取
  • 企业电子商务网站开发百度框架户开户渠道
  • 南京高端网站建设公司哪家好广州网站推广
  • 电销怎么找电话资源四川网站seo