1.首先看一下web.xml主要配置内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置 DispatcherServlet 以处理所有HTTP请求 -->
<servlet>
<servlet-name>app</servlet-name> <!-- 定义 Servlet 的名称 -->
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 指定前端控制器类 -->
<init-param>
<param-name>contextConfigLocation</param-name> <!-- 初始化参数名:上下文配置文件位置 -->
<param-value>classpath:app-context.xml</param-value> <!-- 上下文配置文件的位置,在类路径下查找 -->
</init-param>
<load-on-startup>1</load-on-startup> <!-- 定义在服务器启动时加载该 Servlet 的优先级,数字越小优先级越高 -->
</servlet>
<!-- 将所有请求映射到 DispatcherServlet -->
<servlet-mapping>
<servlet-name>app</servlet-name> <!-- 映射到上面定义的 Servlet 名称 -->
<url-pattern>/</url-pattern> <!-- URL 模式,这里使用 "/" 表示拦截所有请求,但不包括静态资源 -->
</servlet-mapping>
</web-app>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:app-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<multipart-config>
<max-file-size>10485760</max-file-size>
<max-request-size>10485760</max-request-size>
</multipart-config>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
:定义了一个名为app的Servlet,它实际上是一个Spring MVC的前端控制器DispatcherServlet。
:指定了用于处理请求的类,这里是DispatcherServlet。
:初始化参数,指定了Spring应用上下文的位置为classpath:app-context.xml,即从类路径中加载配置文件。
:表示在Web应用启动时立即加载此Servlet,值1表明优先级较高(数值越小优先级越高)。
package com.pyb.config;
import jakarta.servlet.Filter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* Spring Web应用初始化器,用于配置Spring和SpringMVC上下文以及DispatcherServlet映射
*/
public class EpidemicApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private static final Logger logger = LoggerFactory.getLogger(EpidemicApplicationInitializer.class);
/**
* 用来配置ContextLoaderListener创建对应上下文的bean
*/
@Override
protected Class<?>[] getRootConfigClasses() {
logger.info("Loading root configuration classes.");
return new Class[]{SpringConfig.class};
}
/**
* 用于定义DispatcherServlet应用上下文的bean
*/
@Override
protected Class<?>[] getServletConfigClasses() {
logger.info("Loading servlet configuration classes.");
return new Class[]{SpringMVCConfig.class};
}
/**
* 配置拦截器,将所有请求映射到DispatcherServlet
*/
@Override
protected String[] getServletMappings() {
logger.info("Mapping all requests to DispatcherServlet.");
return new String[]{"/"};
}
/**
* 可选:配置过滤器(如果需要)
*/
@Override
protected Filter[] getServletFilters() {
return new Filter[]{new CharacterEncodingFilter("UTF-8", true)};
}
}
类的核心功能介绍
- 加载根配置类
@Override
protected Class<?>[] getRootConfigClasses() {
logger.info(“Loading root configuration classes.”);
return new Class[]{SpringConfig.class};
}
作用:指定哪些配置类应该被用来创建应用的根(全局)Spring应用上下文。这里指定了SpringConfig类作为根配置。
意义:这些配置类中定义的bean可以在整个应用程序中使用,不仅限于Web层。
2. 加载Servlet配置类@Override
protected Class<?>[] getServletConfigClasses() {
logger.info(“Loading servlet configuration classes.”);
return new Class[]{SpringMVCConfig.class};
}
作用:指定哪些配置类应该被用来创建DispatcherServlet的应用上下文。这里指定了SpringMVCConfig类作为Servlet配置。
意义:这些配置类中定义的bean主要用于Web层,例如控制器、视图解析器等。
3. 映射请求到DispatcherServlet@Override
protected String[] getServletMappings() {
logger.info(“Mapping all requests to DispatcherServlet.”);
return new String[]{“/”};
}
作用:定义了哪个URL模式应该由DispatcherServlet处理。这里的"/"表示拦截所有非静态资源的请求。
意义:确保所有进入应用的HTTP请求都会经过Spring MVC框架进行处理。
4. 配置过滤器@Override
protected Filter[] getServletFilters() {
return new Filter[]{new CharacterEncodingFilter(“UTF-8”, true)};
}
作用:可以在这里添加自定义的或内置的过滤器。这段代码添加了一个字符编码过滤器,用于确保所有传入的请求都使用UTF-8编码。
意义:有助于防止乱码问题,特别是在处理国际化内容时。
日志记录
注意到在每个方法内部都有日志记录语句,使用的是SLF4J的日志接口。通过这种方式,开发者可以在应用启动过程中跟踪重要的配置信息,这对于调试和维护非常有帮助。总结
EpidemicApplicationInitializer 类提供了一种现代化的方式来进行Spring Web应用程序的初始化和配置,完全摒弃了web.xml文件,转而采用全Java配置。这样做有几个优点:类型安全:避免了XML配置中的字符串错误。
灵活性:更容易重构和修改配置。
简化部署:减少了对额外配置文件的依赖。
一致性:将所有的配置集中在一个地方,便于管理和理解。
2.用springconfig配置类代替springconfig.xml配置文件
package com.pyb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Spring相关配置(替换掉了spring-bean.xml和spring-tx.xml)
*/
@Configuration
@ComponentScan(basePackages = "com.pyb") // 如果需要扫描所有组件,可以不加过滤器
@EnableTransactionManagement // 启用事务管理器
public class SpringConfig {
private static final Logger logger = LoggerFactory.getLogger(SpringConfig.class);
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
logger.info("Initializing DataSourceTransactionManager with data source: {}", dataSource);
try {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
} catch (Exception e) {
logger.error("Failed to initialize DataSourceTransactionManager", e);
throw new RuntimeException("Failed to initialize DataSourceTransactionManager", e);
}
}
/**
* 数据源配置(根据实际情况调整)
*/
@Bean
public DataSource dataSource() {
org.springframework.jdbc.datasource.DriverManagerDataSource dataSource = new org.springframework.jdbc.datasource.DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/studymysql");
dataSource.setUsername("root");
dataSource.setPassword("123456");
return dataSource;
}
}
- 组件扫描和配置类
@Configuration
@ComponentScan(basePackages = “com.pyb”) // 如果需要扫描所有组件,可以不加过滤器
替代:在spring-bean.xml中使用context:component-scan标签来自动检测并注册带有特定注解(如@Component, @Service, @Repository, @Controller)的bean。
作用:自动扫描指定包及其子包中的组件,并将它们注册为Spring容器中的bean。- 启用事务管理
Java
深色版本
@EnableTransactionManagement // 启用事务管理器
替代:在spring-tx.xml中使用tx:annotation-driven/标签来启用基于注解的事务管理。
作用:允许使用@Transactional注解来标记服务层的方法或类,从而实现声明式事务管理。- 数据源配置
@Bean
public DataSource dataSource() {
org.springframework.jdbc.datasource.DriverManagerDataSource dataSource = new org.springframework.jdbc.datasource.DriverManagerDataSource();
dataSource.setDriverClassName(“com.mysql.cj.jdbc.Driver”);
dataSource.setUrl(“jdbc:mysql://localhost:3306/studymysql”);
dataSource.setUsername(“root”);
dataSource.setPassword(“123456”);
return dataSource;
}
替代:在spring-bean.xml中定义元素来创建DataSource bean。
作用:提供一个JDBC数据源,用于数据库连接池管理,使应用程序能够与数据库交互。
4. 事务管理器配置
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
logger.info(“Initializing DataSourceTransactionManager with data source: {}”, dataSource);
try {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
transactionManager.setDataSource(dataSource);
return transactionManager;
} catch (Exception e) {
logger.error(“Failed to initialize DataSourceTransactionManager”, e);
throw new RuntimeException(“Failed to initialize DataSourceTransactionManager”, e);
}
}
替代:在spring-tx.xml中定义元素来创建PlatformTransactionManager bean。
作用:提供一个事务管理器,用于管理和协调事务,确保多个操作要么全部成功,要么全部失败,以此维护数据的一致性。
3.用springmvc配置类替代springmvc.xml配置文件功能
package com.pyb.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.convert.converter.Converter;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Spring MVC相关配置 (替换掉了springmvc.xml)
*/
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.pyb.controller","com.pyb.config"},
includeFilters = @ComponentScan.Filter(type= FilterType.ANNOTATION, classes = org.springframework.stereotype.Controller.class))
public class SpringMVCConfig implements WebMvcConfigurer {
/**
* 添加视图控制器,如果没有指定,就默认访问这个界面
* @param registry
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("epidemic"); // 访问的是epidemic.jsp
}
/**
* 配置视图解析器(前后缀)
*/
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
resolver.setViewClass(JstlView.class);
return resolver;
}
/**
* 配置日期转换器
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new Converter<String, Date>() {
private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
@Override
public Date convert(String source) {
try {
return dateFormat.parse(source);
} catch (ParseException e) {
throw new IllegalArgumentException("无法解析日期:" + source, e);
}
}
});
}
/**
* 如果没有匹配到action,则使用servlet默认的访问
* @param configurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
组件扫描
@ComponentScan(basePackages = {“com.pyb.controller”, “com.pyb.config”},
includeFilters = @ComponentScan.Filter(type= FilterType.ANNOTATION, classes = org.springframework.stereotype.Controller.class))
作用:指定哪些包需要被扫描以查找带有特定注解(如@Controller)的组件。
意义:确保所有的控制器类都能被Spring容器检测到并注册为bean。视图控制器配置
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController(“/”).setViewName(“epidemic”); // 访问的是epidemic.jsp
}
作用:定义了当用户访问根路径(/)时,直接渲染名为epidemic.jsp的视图,而无需调用任何控制器方法。
意义:简化了对默认页面或首页的访问逻辑。视图解析器配置
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(“/WEB-INF/views/”);
resolver.setSuffix(“.jsp”);
resolver.setViewClass(JstlView.class);
return resolver;
}
作用:设置了视图解析器,指定了JSP视图的前缀和后缀,以及使用的视图类(JstlView),以便于正确地定位和渲染视图。
意义:确保所有返回的视图名称能够被正确解析成实际的视图文件路径。格式化器和转换器注册
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addConverter(new Converter<String, Date>() {
private final SimpleDateFormat dateFormat = new SimpleDateFormat(“yyyy-MM-dd”);@Override
public Date convert(String source) {
try {
return dateFormat.parse(source);
} catch (ParseException e) {
throw new IllegalArgumentException(“无法解析日期:” + source, e);
}
}
});
}
作用:向Spring MVC的格式化器注册表中添加自定义的字符串到日期的转换器。
意义:允许在数据绑定过程中自动将符合特定格式的字符串转换为Date对象,提高了数据处理的便利性。默认Servlet处理
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
作用:启用默认的Servlet处理程序,这意呀着如果Spring MVC找不到匹配的处理器映射,则会将请求转发给容器的默认Servlet来处理。
意义:确保静态资源(如CSS、JavaScript文件)可以被正确服务,同时避免未匹配的请求导致404错误。
4.最后删除web.xml文件,可以测试得出,启动tomcat,web项目依旧可以运行
5.所需依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>6.1.14</version> <!-- 请根据实际情况调整版本号 -->
</dependency>
<!-- Spring JDBC Support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>6.0.9</version> <!-- 请根据实际情况调整版本号 -->
</dependency>
<!-- Spring Transaction Management -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>6.0.9</version> <!-- 请根据实际情况调整版本号 -->
</dependency>
<!-- Thymeleaf Template Engine -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring6</artifactId>
<version>3.1.2.RELEASE</version> <!-- 请根据实际情况调整版本号 -->
</dependency>
<dependency>
<groupId>jakarta.servlet.jsp.jstl</groupId>
<artifactId>jakarta.servlet.jsp.jstl-api</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>3.0.0</version>
</dependency>
<!-- Apache Commons FileUpload for file upload support -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.5</version>
</dependency>
<!-- Servlet API (if not provided by your container) -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version> <!-- 请根据实际情况调整版本号 -->
<scope>provided</scope> <!-- 通常由Servlet容器提供,所以设置为provided -->
</dependency>
<!-- For logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>2.0.7</version>
</dependency>
<!-- Optional: If using Java 8 or above, consider using commons-io as well -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.14.0</version>
</dependency>
</dependencies>