赞
踩
1.HttpServlet。
听起来是不是感觉像是个上古词汇,是不是没有阅读下去的兴趣了?Tomcat知道吧,它就是一个servlet容器,当用户向服务器发送一个HTTP请求时,Servlet容器(如Tomcat)会根据其配置找到对应的Servlet,并调用该Servlet的相关方法来处理请求和生成响应。
HttpServlet
是Java Servlet API中的一个抽象类,位于 javax.servlet.http
包下,用于处理HTTP协议的请求和响应。它是构建Web应用程序时用来处理客户端HTTP请求的核心组件,几乎所有的动态Web应用都会直接或间接地使用到 HttpServlet。它拥有doGet,doPost方法。
我们Java程序员经常到处吹嘘我们做的web程序是MVC架构的,抱着spring mvc的大腿到处讨饭吃,在Spring MVC框架中,Servlet扮演着至关重要的角色,特别是DispatcherServlet作为Spring MVC的核心组件,它是整个Spring Web MVC架构的前端控制器(Front Controller)设计模式的实现。
DispatcherServlet 它就是一个特殊的Servlet,它继承了HttpServlet,并且针对Spring框架进行了专门的设计和优化。在Spring MVC的应用程序中,通常会在web.xml文件中配置DispatcherServlet,以此作为处理所有HTTP请求的入口点。
在Spring MVC的工作流程中,DispatcherServlet的主要职责包括:
请求分发:接收到HTTP请求后,DispatcherServlet根据请求的URL路径信息,解析并匹配到对应的处理器(Controller),并将请求进一步分发给Controller处理。
模型视图映射:Controller处理完请求后,会将控制权交还给DispatcherServlet,此时Controller可能已经准备好了模型数据(Model)。DispatcherServlet根据返回的逻辑视图名(View Name),寻找合适的视图解析器(View Resolver)将逻辑视图转换成实际的视图(如JSP页面、Thymeleaf模板或其他视图技术)。
视图渲染:最终,DispatcherServlet将模型数据传递给选定的视图,由视图负责将数据渲染成最终的HTTP响应内容返回给客户端。
还记得在Spring MVC中,DispatcherServlet的传统配置步骤吗?
我们在web.xml中是这么配置的:
- <!-- web.xml -->
- <web-app>
- <!-- ... -->
- <servlet>
- <servlet-name>dispatcher</servlet-name>
- <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
- <!-- 可选配置:设置Spring MVC配置文件的位置 -->
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
- </init-param>
- <!-- 可选配置:设置DispatcherServlet的加载顺序 -->
- <load-on-startup>1</load-on-startup>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>dispatcher</servlet-name>
- <!-- 配置DispatcherServlet处理哪些请求 -->
- <url-pattern>/</url-pattern> <!-- 通常配置为'/'来处理所有请求 -->
- </servlet-mapping>
- <!-- ... -->
- </web-app>
配置Spring MVC相关的配置文件: 在上面的<init-param>
中指定了contextConfigLocation
,在这里你可以指定Spring MVC相关的配置文件。在这个文件中,可以配置Spring MVC的各种组件,如HandlerMappings、Controllers、ViewResolvers等。
- <!-- /WEB-INF/spring/dispatcher-servlet.xml -->
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
-
- <!-- 配置视图解析器 -->
- <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
- <property name="prefix" value="/WEB-INF/views/" />
- <property name="suffix" value=".jsp" />
- </bean>
-
- <!-- 配置注解驱动 -->
- <mvc:annotation-driven/>
-
- <!-- 配置其他Spring MVC组件,如HandlerMappings、Controllers等 -->
- <!-- ... -->
-
- </beans>
那么web.xml中的servlet为啥这么配置?那就得从一个远古时代说起了,比如我们定义一个关于啤酒的servlet并且拦截的是/Tester.do这个路径,就是如下的配法,是不是大差不差。
而init-param呢?它就是这个servlet自己的参数。DispatcherServlet就可以通过getServletConfig().getInitParameterNames();去获取我们MVC定义的东西了。
2.ServletContext。
在Java Servlet规范中,ServletContext
是一个接口,它表示Web应用的全局上下文信息。每一个部署在Servlet容器(如Tomcat、Jetty等)中的Web应用都有一个与之关联的ServletContext
实例,它在Web应用启动时由Servlet容器创建并贯穿整个应用生命周期。在古老的配置中是这么定义的:
ServletContext
主要功能包括:
属性管理:
setAttribute
方法向ServletContext
中存储全局应用范围的对象,这些对象可供同一个Web应用中的所有Servlet、Filter或JSP页面共享和访问。getAttribute
方法获取存储在ServletContext
中的属性值。资源访问:
getResourceAsStream(String path)
可以从类路径或Web应用根目录下获取资源流。初始化参数:
web.xml
文件中为整个Web应用定义初始化参数,然后通过getInitParameter(String name)
和getInitParameterNames()
方法来访问这些参数。监听器注册:
ServletContextListener
监听器,以便在Web应用启动和停止时执行一些初始化和清理工作。Servlet注册:
ServletRegistration
接口注册Servlet。Session管理:
HttpSession
实例,但通常在Servlet或Filter中直接通过HTTP请求对象获取。获取MIME类型:
getMimeType(String file)
方法可以获得指定文件名的MIME类型。总之,ServletContext
为Web应用提供了一个共享的全局环境,使得应用中的各个组件能够进行有效的通信和资源共享,同时也是实现Web应用初始化、配置和管理的重要手段。在Spring MVC中,WebApplicationContext
就是对ServletContext
进行了扩展,以更好地与Spring框架集成。
WebApplicationContext是不是听着很熟悉了?
它是Spring提供的一种特殊的应用上下文,它是ApplicationContext接口的扩展,专为Web应用而设计。WebApplicationContext不仅包含了常规Spring IoC容器的所有功能,还与Servlet容器的ServletContext
紧密关联,它可以被绑定到Servlet容器的ServletContext
上,使得Spring Bean可以访问到ServletContext
的资源和服务。
即可以与Servlet容器(如Tomcat、Jetty等)中的 ServletContext
相关联,使得Spring应用能够访问到Web容器的全局上下文信息。
在Servlet容器启动时,通过 ContextLoaderListener
或 DispatcherServlet
可以自动创建和绑定 WebApplicationContext
。
那么ApplicationContext又是啥呢?
ApplicationContext
接口是Spring框架中的一个重要组成部分,它是Spring IoC容器(Inversion of Control Container)的核心接口之一,扩展自BeanFactory
接口,提供了更多用于企业级Java应用的功能。
ApplicationContext
的主要作用和特点包括:
Bean管理:
依赖注入(DI)支持:
资源访问:
国际化与消息处理:
MessageSource
接口,支持国际化的消息处理,可以根据不同的语言环境加载相应的消息资源。事件发布与监听:
ApplicationEventPublisher
接口发布和接收应用范围内的事件。AOP支持:
环境配置:
EnvironmentCapable
接口,可以访问应用运行时的环境信息,包括属性配置、profiles等。多层级容器支持:
常见的ApplicationContext
实现类有:
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
AnnotationConfigApplicationContext
XmlWebApplicationContext
(适用于Web应用,与Servlet容器集成)使用ApplicationContext
代替基本的BeanFactory
,可以更容易地获得更复杂的企业级功能支持,是构建大型、复杂Spring应用的推荐选择。
那ApplicationContext和WebApplicationContext的关系就能连上了。WebApplicationContext
是针对Web环境的专用应用上下文,它在 ApplicationContext
的基础之上添加了Web应用特性的支持,使得Spring框架能够更好地应用于Web应用程序的开发之中。在实际使用中,当开发Web应用时,通常会使用 WebApplicationContext
作为IoC容器,以充分利用其针对Web环境所提供的增强功能。
那种年龄比较大的程序员可能见过这俩配置文件:applicationContext.xml 和 servlet-context.xml
applicationContext.xml(Spring 核心配置)
例子:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
-
- <!-- 扫描服务、DAO和其他非MVC层的组件 -->
- <context:component-scan base-package="com.example.service, com.example.dao"/>
-
- <!-- 其他Spring核心配置,如数据源、事务管理等 -->
-
- </beans>
servlet-context.xml 或 spring-servlet.xml (Spring MVC配置)
例子:
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:mvc="http://www.springframework.org/schema/mvc"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
-
- <!-- 扫描Controller组件 -->
- <context:component-scan base-package="com.example.web.controller"/>
-
- <!-- 开启Spring MVC注解支持 -->
- <mvc:annotation-driven/>
-
- <!-- 视图解析器配置等其他MVC相关配置 -->
-
- </beans>
两者的联系在于:
servlet-context.xml
可以继承applicationContext.xml
中的Bean定义。web.xml
配置使得DispatcherServlet
加载servlet-context.xml
时,同时使servlet-context.xml
成为applicationContext.xml
的子上下文,从而使得全局配置的Bean能被所有MVC相关的Bean所访问,同时又能在MVC上下文中定义特定的Web组件。总结来说applicationContext.xml
负责非Web相关的一般性应用组件的配置,而servlet-context.xml
负责与Web相关的MVC组件的具体配置,两者共同构建起完整的Spring Web应用上下文层次结构。
那么新程序员见到的配置大概如下:
AppConfig.java (Spring 核心配置)
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.ComponentScan;
-
- @Configuration
- @ComponentScan(basePackages = {"com.example.service", "com.example.dao"})
- public class AppConfig {
- // 可以在这里添加额外的@Bean定义或其他配置
- }
WebConfig.java (Spring MVC配置)
- import org.springframework.context.annotation.Configuration;
- import org.springframework.web.servlet.config.annotation.EnableWebMvc;
- import org.springframework.web.servlet.config.annotation.ComponentScan;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
- @Configuration
- @EnableWebMvc
- @ComponentScan(basePackages = "com.example.web.controller")
- public class WebConfig implements WebMvcConfigurer {
- // 可以在此重写或添加WebMvcConfigurer接口的方法来自定义MVC配置
- }
为啥上面在Spring 注册Bean时之所以常常会特意排除Controller组件的自动扫描,什么原因呢?
容器角色分工:
容器初始化和性能优化:
请求处理流程的集中管理:
DispatcherServlet
转发请求至对应的Controller,使用@RequestMapping
等注解映射请求。如果Controller也在核心容器中扫描注册,就需要额外配置请求的路由规则,不如直接在Spring MVC容器中管理来得自然和高效。上下文层次关系:
因此,在Spring应用的配置中,通常会在Spring MVC配置中单独指定扫描Controller所在的包路径,而在核心Spring配置中则扫描除Controller之外的服务、DAO等组件所在的包,以此达到合理的容器组织和性能优化的目的。
就这么使得spring 和 web容器怼一块了,在此基础上封装了很多拿来就用的东西,让sping蓬勃发展起来,造就了现在Java程序员失业的现状。
3.listener。
我们再看一下这个图:
在上面古老的例子里,我们看到web容器的context上下文配置的都是字符串,那只是字符串可不中,我们来看一下这个美女的担忧。
不过,在此之后谁将这个String参数转换成由Web应用各部分共享的一个具体DataSource引用呢?
不能把这个代码放在servlet中,因为你选择谁作为第一个servlet来查找DataSource,并把它存储在一个属性中呢?你真的想保证总是让某个特定的servlet最先运行吗?好好考虑一下。
噢,如果整个Web应用有一个main方法就好了。能放一些在servlet之前运行的代
码….…..
这个时候你才发现servlet没有main方法。
那么我们的listener就登场了。看一下怎么定义一个古老的listener:
比如我们初始化一个狗对象,放到上下文中去。
然后在web.xml中定义这个listener就好了。
看起来是不是很熟悉了,对,我们的spring里也有这样的配置,来看ContextLoaderListener怎么定义到web.xml中去的:
- <!-- web.xml -->
- <web-app>
- <!-- ... -->
- <listener>
- <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
- </listener>
-
- <!-- 指定Spring配置文件位置 -->
- <context-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>/WEB-INF/applicationContext.xml</param-value>
- </context-param>
- <!-- ... -->
- </web-app>
ContextLoaderListener的作用:
ContextLoaderListener
监听器会在Web应用启动时自动创建和初始化Spring应用上下文(ApplicationContext),这个上下文通常包含那些不需要依赖HTTP请求即可初始化的Bean,如服务层、数据访问层组件等。context-param
标签可以指定Spring配置文件的位置,ContextLoaderListener
会读取这些配置文件来初始化Spring应用上下文。是不是一下子就对应上了?应该就清晰listener的工作职责了吧。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。