凯哥Java 2020-02-16
web容器(web服务器)主要有:Apache、IIS、Tomcat、Jetty、JBoss、webLogic等,而Tomcat、Jetty、JBoss、webLogic同时也是servlet容器,或者说他们还包含了servlet容器。没有servlet容器,你也可以用web容器直接访问静态页面,比如安装一个apache等,但是如果要显示jsp/servlet,你就要安装一个servlet容器了,但是光有servlet容器是不够的,因为它要被解析成html输出,所以你仍需要一个web容器。大多数servlet容器同时提供了web容器的功能,也就是说大多servelt容器可以独立运行你的web应用。
web容器是管理servlet(通过servlet容器),以及监听器(Listener)和过滤器(Filter)的。这些都是在web容器的掌控范围里。但他们不在spring和springmvc的掌控范围里。因此,我们无法在这些类中直接使用Spring注解的方式来注入我们需要的对象,是无效的,web容器是无法识别的。
引用自下文:https://www.cnblogs.com/jieerma666/p/10805966.html
Tomcat 7以上的版本支持Servlet3.0。在Servlet 3.0环境中,当容器启动时,容器会在类路径中查找ServletContainerInitializer接口的实现类,如果发现这样的类就会用这个类来配置Servlet容器(Tomcat,Jetty)。
javax.servlet.ServletContainerInitializer
在spring中有存在一个SpringServletContainerInitializer类实现了ServletContainerInitializer接口,SpringServletContainerInitializer类在onStartup方法中又去查找
WebApplicationInitializer接口的实现类,在spring中有一个WebApplicationInitializer的实现类AbstractAnnotationConfigDispatcherServletInitializer。因此只要继承AbstractAnnotationConfigDispatcherServletInitializer类就可以配置DispatcherServlet与Spring的ApplicationContext(Spring的核心接口,是BeanFactory接口的子接口)。
org.springframework.web.SpringServletContainerInitializer org.springframework.web.WebApplicationInitializer org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
下面就是扩展AbstractAnnotationConfigDispatcherServletInitializer的类
package spitter.config;
import javax.servlet.Filter;
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import spitter.web.MyFilter;
public class SpitterWebApplication extends AbstractAnnotationConfigDispatcherServletInitializer{
/**
* 指定主配置类
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[]{RootConfig.class};
}
/**
* 指定springMVC配置类
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[]{WebConfig.class};
}
/**
* 将一个或者多个路径映射到DispatcherServlet上
*/
@Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
/**
* 当AbstractAnnotationConfigDispatcherServletInitializer 将DispatcherServlet注册到Servlet容器之后,
* 就会调用customizeRegistration方法,并把Servlet注册之后得到的Registration.Dynamic传递过来,通过重写
* customizeRegistration方法,我们可以对DispatcherServlet进行额外的配置
*/
@Override
protected void customizeRegistration(Dynamic registration) {
System.out.println("dispatcherServlet已经注册完成");
registration.setMultipartConfig(new MultipartConfigElement("/tmp/spitter/uploads"));
}
@Override
protected Filter[] getServletFilters() {
// TODO Auto-generated method stub
return new Filter[] {new MyFilter()};
}
}一个是Spring的应用上下文,是由ContextLoaderListener监听器进行创建,这个监听器是一个ServletContextListener的子类,也就是ServletContext监听器。这个应用上下文加载应用中的业务层与数据访问的的一些bean.
另一个是SpringMVC的应用上下文,是由DispatcherServlet启动时创建的。这个应用上下文加载一个Web组件的bean,例如控制器,视图解析器,以及处理器映射器。
以前连个应用上下文在创建时都需要都xml配置文件,两个上下文的配置文件的位置在web.xml中进行配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
id="WebApp_ID" version="3.0">
<!-- 在ServletContextListener中初始化spring容器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-context.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 在DispatcherServlet中初始化springMVC容器 -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 设置过滤器,设置字符编码 -->
<!-- 字符编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<init-param>
<param-name>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResposeEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置cxf的核心控制器 -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<!-- 所有来自/webservice/*的请求交给cxf处理 -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/webservice/*</url-pattern>
</servlet-mapping>
</web-app>和Servlet 3.0结合之后,就可以采用两个java配置类代替xml配置文件
package spitter.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
@Configuration
@ComponentScan(basePackages = {"spitter"},excludeFilters (type=FilterType.ANNOTATION,value=EnableWebMvc.class))
public class RootConfig {
}package spitter.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
@Configuration//声明为配置类
@EnableWebMvc//启动SpringMVC组件。如果在xml配置,也可以采用<mvc:annotation-driven>标签启动
@ComponentScan("spitter.web")//启动扫描组件
public class WebConfig extends WebMvcConfigurationSupport {
//配置视图解析器
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver=new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setExposeContextBeansAsAttributes(true);
return resolver;
}
//配置静态资源处理
@Override
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();//通过调用enable()方法,我们要求DispatcherServlet对静态资源的请求转发到
//Servlet容器中默认的Servlet上,而不是使用DispatcherServlet本身来处理静态资源请求。
}
}