1、新建maven 工程
2、设置pom.xml打包方式为war
<packaging>war</packaging>
3.添加webapp 和web.xml,调整文件路径 /src/webapp/web-inf/web.xml
4、添加常用pom坐标 dependency
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>6.2.0.jre8</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
5、添加资源文件,用于连接数据库使用 src/main/resources/jdbc.properties
配置数据库访问信息
jdbc.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
jdbc.url=jdbc:sqlserver://localhost:1433;DatabaseName=demo
jdbc.username=sa
jdbc.password=***
6、添加 mvc 配置代码(本案例不使用xml配置)
添加包层级结构(相当于C#命名空间)
org.example.config (mvc参数控制配置)
org.example.controller (servlet控制)
org.example.dao (数据库访问层)
org.example.entity (实体类)
org.example.service(服务类,用于与数据库访问层交互)
6.1 添加配置类
//添加 org.example.config.SpringConfig
package org.example.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
@Configuration //告诉Spring这是一个配置类
@ComponentScan({"org.example.services"})
@PropertySource("classpath:jdbc.properties")
//用import管理所有的@Configuration配置类,保证@Configuration本身是按照功能、业务、职责独立划分的
//import 只能使用一次,如果多个使用数组方式加载
@Import({JdbcConfig.class,MyBatisConfig.class})
@EnableTransactionManagement //开启事务
public class SpringConfig {
}
package org.example.config;
import com.itheima.controller.interceptor.ProjectInterceptor;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
@ComponentScan({"org.example.controller","org.example.config"})
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer{ //
private final ProjectInterceptor projectInterceptor;
public SpringMvcConfig(ProjectInterceptor projectInterceptor) {
this.projectInterceptor = projectInterceptor;
}
//拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(projectInterceptor).addPathPatterns("/stu/**","/tech/**");
}
//静态资源处理
//addResoureHandler:指的是对外暴露的访问路径
//addResourceLocations:指的是内部文件放置的目录
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// //注解配置放行指定资源格式
registry.addResourceHandler("/pages/**").addResourceLocations("/pages");
}
//页面跳转
//以前写SpringMVC的时候,如果需要访问一个页面,必须要写Controller类,
//然后再写一个方法跳转到页面,感觉好麻烦,其实重写WebMvcConfigurer中的addViewControllers方法即可达到效果了
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/toLogin").setViewName("login");
}
/**
* 配置请求视图映射
* @return
*/
@Bean
public InternalResourceViewResolver resourceViewResolver()
{
InternalResourceViewResolver internalResourceViewResolver = new InternalResourceViewResolver();
//请求视图文件的前缀地址
internalResourceViewResolver.setPrefix("/WEB-INF/jsp/");
//请求视图文件的后缀
internalResourceViewResolver.setSuffix(".jsp");
return internalResourceViewResolver;
}
/**
* 视图配置
* @param registry
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
super.configureViewResolvers(registry);
registry.viewResolver(resourceViewResolver());
/*registry.jsp("/WEB-INF/jsp/",".jsp");*/
}
/*
* 跨域
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping("/cors/**")
.allowedHeaders("*")
.allowedMethods("POST","GET")
.allowedOrigins("*");
}
/**
* 消息内容转换配置
* 配置fastJson返回json转换
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
//调用父类的配置
super.configureMessageConverters(converters);
//创建fastJson消息转换器
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//创建配置类
FastJsonConfig fastJsonConfig = new FastJsonConfig();
//修改配置返回内容的过滤
fastJsonConfig.setSerializerFeatures(
SerializerFeature.DisableCircularReferenceDetect,
SerializerFeature.WriteMapNullValue,
SerializerFeature.WriteNullStringAsEmpty
);
fastConverter.setFastJsonConfig(fastJsonConfig);
//将fastjson添加到视图消息转换器列表内
converters.add(fastConverter);
}
}
而WebMvcConfigurer配置类其实是Spring
内部的一种配置方式,可以自定义一些Handler,Interceptor,ViewResolver,MessageConverter等等的东西对springmvc框架进行配置。
addInterceptor:需要一个实现HandlerInterceptor接口的拦截器实例
addPathPatterns:用于设置拦截器的过滤路径规则;addPathPatterns(“/**”)对所有请求都拦截
excludePathPatterns:用于设置不需要拦截的过滤规则
拦截器主要用途:进行用户登录状态的拦截,日志的拦截等。
//org.example.config.JdbcConfig
//整合jdbc
package org.example.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
public class JdbcConfig {
@Value("${jdbc.driver}")
private String driver;
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
@Value("${jdbc.password}")
private String password;
//配置JDBC数据源
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
if(driver.indexOf("sqlserver")>-1){
dataSource.setValidationQuery("select 'x'");//SQL SERVER
}
return dataSource;
}
//Spring进行了统一的抽象,形成了PlatformTransactionManager事务管理器接口,事务的提交、回滚等操作全部交给它来实现。
@Bean
public PlatformTransactionManager platformTransactionManager(DataSource dataSource){
DataSourceTransactionManager ds = new DataSourceTransactionManager();
ds.setDataSource(dataSource);
return ds;
}
}
//@Bean是一个方法级别上的注解,主要用在@Configuration注解的类里,也可以用在@Component注解的类里。添加的bean的id为方法名
以上Bean等同于
<beans>
<bean id="dataSource" class="org.example.config.JdbcConfig"/><bean id="platformTransactionManager" class="org.example.config.JdbcConfig"/>
</beans>
//Spring 整合mybatis
package org.example.config;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import javax.sql.DataSource;
public class MyBatisConfig {
//在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的,而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建。Spring 将会在应用启动时为你创建 SqlSessionFactory,并使用 sqlSessionFactory 这个名字存储起来
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
//mybatis的typeAliasesPackage属性的作用是,搜索指定包别名。
factoryBean.setTypeAliasesPackage("com.itheima.domain");
return factoryBean;
}
//mybatis-spring提供了MapperScannerConfigurer这个类,它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean。MapperScannerConfigurer是spring和mybatis整合的mybatis-spring的jar包中提供的一个类
//扫描Mapper接口类所在的包,为mapper创建实现类,包扫描是创建实现类的,并没有加载对应的映射文件。但是,如果映射文件和映射接口在一个包内,就会自动加载映射文件。
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer msc = new MapperScannerConfigurer();
msc.setBasePackage("org.example.dao"); //指定mapper 包
return msc;
}
}
//ServletConfig就代表当前Servlet在web.xml中的配置信息。
package org.example.config;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class ServletConfig extends AbstractAnnotationConfigDispatcherServletInitializer {
//配置root上下文,如Jpa数据源等等的配置
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//配置dispatcher servlet,如果在root config指定了该转发规则就可以忽略
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
//指定开始被servlet处理的url,配置从/开始
//对 getServletMappings() 的进一步说明:
//通常情况下,大家配置spring mvc的路径拦截(ServletMapping)都习惯配置“/”
//但在某些特殊场景下,你可能希望所有的mvc的路径都有个固定的前缀,形如“/springmvc/*”,
//如果你在springmvc的ServletMapping中配置了这种路径,那么你的URL访问地址和controller的path就要注意了:如果你的地址栏URL为"/springmvc/user",那么你的controller中的path就必须配置"/user",因为spring mvc拦截了所有以“/springmvc”为前缀的请求,而在匹配的时候也截掉了“/springmvc”,用剩下的“/user”匹配controller。
//如果路径设置为“/”,则所有的请求都会由DispatcherServlet处理。
@Override
protected String[] getServletMappings() {
return new String[]{"/api/*"};
}
//配置servlet过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
DelegatingFilterProxy securityFilterChain = new DelegatingFilterProxy("springSecurityFilterChain");
return new Filter[] {characterEncodingFilter, securityFilterChain};
}
//当registerDispatcherServlet完成时自定义registration
@Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setInitParameter("defaultHtmlEscape", "true");
registration.setInitParameter("spring.profiles.active", "default");
}
}
//AbstractAnnotationConfigDispatcherServletInitializer会同时创建DispatcherServlet和ContextLoaderListener。是传统web.xml方式的替代方式,在servlet3.0中web.xml启动时会检测该接口实现类。
DispatcherServlet启动时,创建Spring应用上下文并加载配置文件或配置类中声明的bean;在Spring web应用中,通常还有由ContextLoaderListener创建的另一个上下文。
DispatcherServlet加载包含Web组件的bean,如控制器、视图解析器以及处理器映射;
ContextLoaderListener加载应用中的其它bean,通常指驱动应用后端的中间层和数据层组件。
在基础的 MyBatis 用法中,是通过 SqlSessionFactoryBuilder 来创建 SqlSessionFactory 的,而在 MyBatis-Spring 中,则使用 SqlSessionFactoryBean 来创建。要创建工厂 bean,将下面的代码放到 Spring 的 XML 配置文件中:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="dataSource" ref="dataSource" />
</bean>
从Spring3.0,@Configuration
用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext
或AnnotationConfigWebApplicationContext
类进行扫描,并用于构建bean定义,初始化Spring容器。
用@Configuation
注解一个类,这个类相当于Spring容器的应用上下文(xml)
配置类
package test;
import org.springframework.context.annotation.Configuration;
@Configuration
public class BeansContainer {
public BeansContainer(){
System.out.println("启动spring容器");
}
}
相当于,这个xml应用上下文
<?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" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:util="http://www.springframework.org/schema/util" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd" default-lazy-init="false">
</beans>
6.1.2 @ComponentScan({"org.exaple.services"})
ComponentScan做的事情就是告诉Spring从哪里找到bean
由你来定义哪些包需要被扫描。一旦你指定了,Spring将会在被指定的包及其下级包中寻找bean
@ComponentScan:会自动扫描包路径下面的所有被@Controller、@Service、@Repository、@Component 注解标识的类,然后装配到Spring容器中。
@ComponentScan的属性: value指定扫描的包,includeFilters包含那些过滤,excludeFilters不包含那些过滤,useDefaultFilters默认的过滤规则是开启的,如果我们要自定义的话是要关闭的。其中@Filters是一个过滤器的接口。@Filters 指过滤规则,FilterType指定过滤的规则
FilterType.ANNOTATION:按照注解 FilterType.ASSIGNABLE_TYPE:按照给定的类型; FilterType.ASPECTJ:使用ASPECTJ表达式 FilterType.REGEX:使用正则指定 FilterType.CUSTOM:使用自定义规则) classes指定过滤的类
等同于一下xml
<context:component-scan base-package="org.exaple.services"/>
6.1.3 @PropertySource("classpath:jdbc.properties")
@PropertySource注解用来指定要读取的配置文件的路径从而读取这些配置文件,可以同时指定多个配置文件;
@PropertySource(value = {"classpath:common.properties", "classpath:abc.properties"})
读取值方法:@Value("${connect.api.apiKeyId}")用来读取属性key=connect.api.apiKeyId所对应的值并把值赋值给属性apiKeyId;
在spring mvc中,在配置文件中的东西,可以在java代码中通过注解进行读取了:
如果发现missing.properties不存在,则抛出异常,也可以使用ignoreResourceNotFound=true去忽略
@Configuration
@PropertySource(value="classpath:missing.properties", ignoreResourceNotFound=true)
public class AppConfig {
//...
}