一、Spring部分
1. Spring 的含义:
Spring
在不同的场景中表示不同的含义。早期的时候它被用来指代Spring Framework项目本身,这也是它一开始的含义。随着时间的推移,在Spring Framework之上建立了其他Spring项目,比如SpringSecurity、SpringBoot、SpringCloud
。大部分情况下,当人们聊到Spring时,他们所说的 Spring 是 Spring 整个家族。
Spring 是一个轻量级的开源框架,是为解决企业应用开发的复杂性而创建的。而在我的理解中,Spring 的主要就解决了两件事情(当然它还解决了数据访问、远程调用、单元测试等问题),分别对应 Spring 的两个设计思想 IOC 和 AOP:
- IOC 容器(解耦合):解决各种 new 对象的问题
- AOP (切面编程):把非业务范畴的功能,提取成一个切面,统一实现
2. 核心特性(Core)
- IoC 容器(IoC Container)
- Spring 事件(Events)
- 资源管理(Resources)
- 国际化(i18n)
- 校验(Validation)
- 数据绑定(Data Binding)
- 类型转换(Type Conversion)
- Spring 表达式(Spring Express Language)
- 面向切面编程(AOP)
这里我们就可以解释BeanFactory和ApplicationContext的区别了:
public interface BeanFactory {
// 根据bean名字查找
Object getBean(String name) throws BeansException;
// Bean延迟查找
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
// 判断容器中有没有这个名字的bean
boolean containsBean(String name);
// 判断一个Bean是不是单例
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
...
}
BeanFactory 看下去可以去做IOC当中的大部分事情,为什么还要去定义一个ApplicationContext 呢?
我们可以看一下ApplicationContext 的 结构图
从图中可以看到 ApplicationContext 它由BeanFactory接口派生而来,因而提供了BeanFactory所有的功能。除此之外context包还提供了以下的功能:
- MessageSource, 提供国际化的消息访问
- 资源访问,如URL和文件
- 事件传播,实现了ApplicationListener接口的bean
- 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
3. IOC
3.1 什么是IOC?
IoC 全称为 Inversion of Control,翻译为 “控制反转”,说白了,IOC 就是由 Spring IOC 容器来负责对象的生命周期和对象之间的关系。
所谓控制:就是对象的创建、初始化、销毁。
- 创建对象:原来是 new 一个,现在是由 Spring 容器创建。
- 初始化对象:原来是对象自己通过构造器或者 setter 方法给依赖的对象赋值,现在是由 Spring 容器自动注入。
- 销毁对象:原来是直接给对象赋值 null 或做一些销毁操作,现在是 Spring 容器管理生命周期负责销毁对象。
所谓反转:
其实是反转的控制权,前面提到是由 Spring 来控制对象的生命周期,那么对象的控制就完全脱离了我们的控制,控制权交给了 Spring 。这个反转是指:我们由对象的控制者变成了 IOC 的被动控制者。
总结:IOC 解决了繁琐的对象生命周期的操作,解耦了我们的代码。
3.2 IOC 能做什么?
IOC 容器完美解决了耦合问题,甚至可以让互不相关的对象产生注入关系。
在 IOC 模式下,你只需要设计良好的流程和依赖,定义出需要什么,然后把控制权交给 Spring 即可。
3.3 IOC、DI、DL的区别
DI和DL:即依赖注入和依赖查找。
我们常说IOC和DI,却忽略了DL,其实后两者都是IOC的具体实现,在Spring中主要运用到的是DI,但并不代表没有DL(依赖查找)。例如我们刚学Spring时写的测试程序。
依赖注入主要分为 手动模式 和 自动模式
- 手动模式:XML 资源配置元信息,Java 注解配置元信息,API 配置元信息
自动装配的局限性和缺点:
- 通过
property
和constructor-arg
进行依赖设定,这种显式的设定始终会覆盖自动装配。你不能自动装配简单的属性,例如基本类型,Strings
,和Classes
(以及这些简单属性的数组)。这种限制是由设计造成的。 - 自动装配不如显示装配精确。如前表所述,尽量小心让Spring避免去猜测模棱两可的事情(知秋注:比如两个相同类型的bean,也没有其他特殊指定,Spring不知道该选择哪个来进行注入操作),以免产生意想不到的结果。如果你不仔细,你的Spring所管理对象之间的关系不再明确。
- 装配信息可能对从Spring容器中生成文档的工具不可用。
- 容器内的多个bean definition可能与要自动装配的setter方法或构造函数参数指明的类型匹配。对于数组,集合,或者
Map
实例,这就不是什么问题了。然而,对于期望单值的依赖项来说,这种歧义性不能随意的解决。如果没有唯一的bean可用,将抛出一个异常。
总结:IOC 是一种设计思想。从 IOC 到 DI 和 DL ,就是从理论到实践。程序把依赖交给容器,容器帮你管理依赖,这就是依赖注入的核心。依赖注入降低了开发的成本,提高了代码复用率、软件的灵活性
4. Spring常见注解:
@Autowired
自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。
@Autowired和@Inject、@Resource,可以与@Qualifier或者@Name配合使用,防止多实例注入时出错,以及值注入@Value。
注解 | 解析 | 用法 |
---|---|---|
@Autowired | 通过AutowiredAnnotationBeanPostProcessor类实现的依赖注入,默认是根据类型进行注入的,因此如果有多个类型一样的Bean候选者,则需要限定其中一个候选者,否则将抛出异常。 | 可注释在字段上,在方法上 |
@Inject | 作用与@Autowired一样 | 可注释在字段上,在方法上、构造器上 |
@Resource | 默认按照名称进行装配,名称可以通过name属性进行指定 | 可注释在字段上,在方法上 |
@Qualifier | 限定描述符除了能根据名字进行注入,更能进行更细粒度的控制如何选择候选者,可与@Autowired或者@Inject进行组合使用,进行精确注入 | 可注释字段上,在方法上、参数上以及注解中 |
@Scope
作用域和生命周期
@Scope 声明 Spring Bean 的作用域 ,四种常见的 Spring Bean 的作用域:
- singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。
- prototype : 每次请求都会创建一个新的 bean 实例。
- request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。
- session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。
具有4个作用域,以及生命周期过程处理@PostConstruct、@PreDestroy 。
注解 | 解析 | 用法 |
---|---|---|
@Scope | 具有4个作用域singleton,prototype,session,request,默认为singleton单例模式 | 可注释在Class创建时 |
@PostConstruct | 相当于init-method,使用在方法上,当Bean初始化时执行 | 可注释在方法上 |
@PreDestroy | 相当于destory-method,使用在方法上,当Bean销毁时执行 | 可注释在方法上 |
案例:
@Service //组件注入,注明为service组件
@Scope("prototype")//声明Scope为Prototype
public class UseFunctionService {
@Autowired //默认按type注入
@Qualifier("functionService") //精确注入
FunctionService functionService;
@Resource(name="baseDao")//默认按name注入,可以通过name和type属性进行选择性注入
private BaseDao baseDao;
@Inject
@Qualifier("userServiceImpl") //精确注入
public IUserService userService;
@PostConstruct//执行完构造函数后执行
public postConstruct(){
System.out.println("postConstruct");
}
@PreDestroy//在销毁Bean前执行
public perDestroy(){
System.out.println("perDestroy");
}
@Autowired
public void setUserDao(@Qualifier("userDao") UserDao userDao) {
this.userDao = userDao;
}
public String SayHello(String word){
return functionService.sayHello(word);
}
}
@Component
,@Repository
,@Service
, @Controller
@component,而其余 @Controller、@Service、@Repository都组合了@component注解,主要为便于使用者Class组件进行归类。默认加载IOC容器中的组件,容器启动会调用无参构造器创建对象,再进行初始化赋值等操作
注解 | 解析 | 用法 |
---|---|---|
@Component | 组件注解,使用了该注解会基于注释的配置和类路径扫描时,会自动扫描并加载Class到ICO容器中 | 注释在类上 |
@Controller | 应用在MVC层(控制层)DispatcherServlet会自动扫描注解了此注解的类,然后将web请求映射到注解了@RequestMapping的方法上 | 注释在类上 |
@Service | 对应服务层,主要涉及一些复杂的逻辑,应用在service层(业务逻辑层) | 注释在类上 |
@Repository | 对应持久层即 Dao 层,主要用于数据库相关操作,应用在dao层(数据访问层) | 注释在类上 |
@Configuration
一般用来声明配置类,可以使用 @Component
注解替代,不过使用Configuration
注解声明配置类更加语义化。 主要区别在于Configuration
在Spring加载的时候,会被CGLib代理,里面的@Bean不会出现重复实例化
官方有说到 ->
@Bean methods are to be declared within @Configuration classes, ensuring that “full” mode is always used and that cross-method references therefore get redirected to the container’s lifecycle management. This prevents the same @Bean method from accidentally being invoked through a regular Java call, which helps to reduce subtle bugs that can be hard to track down when operating in “lite” mode.
机器翻译:在常见的场景中,@Bean方法将在@Configuration类中声明,以确保始终使用“full”模式,并因此将交叉方法引用重定向到容器的生命周期管理。这可以防止通过常规Java调用意外调用相同的@Bean方法,这有助于减少在“lite”模式下操作时难以跟踪的细微bug。
注:读取配置信息@Value,事务注解@Transactional等,还有很多注解就不一一赘述了
二、SpringMVC部分
1. SpringMVC的含义
- 概念:SpringMVC是Spring框架中的一个分支,是基于Java实现MVC的轻量级Web框架
- 核心:Spring的web框架围绕DispatcherServlet [ 调度Servlet ] 设计的。
总结: SpringMVC 本质上还是在使用Servlet处理,并在其基础上进行了封装简化了开发流程,提高易用性、并使用程序逻辑结构变得更清晰
2. SpringMVC的执行流程
3. SpringMVC常见注解
@RequestMapping
处理常见的 HTTP 请求类型
5 种常见的请求类型:
- GET :请求从服务器获取特定资源。举个例子:
GET /users
(获取所有用户) - POST :在服务器上创建一个新的资源。举个例子:
POST /users
(创建用户) - PUT :更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:
PUT /users/12
(更新编号为 12 的用户) - DELETE :从服务器删除特定的资源。举个例子:
DELETE /users/12
(删除编号为 12 的用户) - PATCH :更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少。
注解 | 解析 |
---|---|
@GetMapping | @GetMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.GET) |
@PostMapping | @PostMapping("users") 等价于@RequestMapping(value="/users",method=RequestMethod.POST) |
@PutMapping | @PutMapping("/users/{userId}") 等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.PUT) |
@DeleteMapping | @DeleteMapping("/users/{userId}") 等价于@RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE) |
前后端传值@PathVariable
和 @RequestParam
@PathVariable
用于获取路径参数,@RequestParam
用于获取查询参数。
举个简单的例子:
@GetMapping("/users/{userId}/teachers")
public List<Teacher> getKlassRelatedTeachers(
@PathVariable("userId") Long userId,
@RequestParam(value = "type", required = false) String type){
...
}
如果我们请求的 url 是:/users/{123456}/teachers?type=web
那么我们服务获取到的数据就是:userIDd=123456,type=web
。
@RequestBody
用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter
或者自定义的HttpMessageConverter
将请求的 body 中的 json 字符串转换为 java 对象。
@RestController
@ResponseBody
注解的作用是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,常见于前后端分离项目。
而@RestController
注解是@Controller和
@ResponseBody
的合集,表示这是个控制器 bean,并且是将函数的返回值直 接填入 HTTP 响应体中,是 REST 风格的控制器。
JSR303 一套JavaBean参数校验的标准
它定义了很多常用的校验注解 一些常用的字段验证的注解
@NotEmpty
被注释的字符串的不能为 null 也不能为空@NotBlank
被注释的字符串非 null,并且必须包含一个非空白字符@Null
被注释的元素必须为 null@NotNull
被注释的元素必须不为 null@AssertTrue
被注释的元素必须为 true@AssertFalse
被注释的元素必须为 false@Pattern(regex=,flag=)
被注释的元素必须符合指定的正则表达式@Email
被注释的元素必须是 Email 格式。@Min(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值@Max(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值@DecimalMin(value)
被注释的元素必须是一个数字,其值必须大于等于指定的最小值@DecimalMax(value)
被注释的元素必须是一个数字,其值必须小于等于指定的最大值@Size(max=, min=)
被注释的元素的大小必须在指定的范围内
三、mybatis部分
1. mybatis的含义
MyBatis
的前身是 iBatis
,iBatis是 Apache 软件基金会下的一个开源项目。2010 年该项目从Apache 基金会迁出,并改名为MyBatis。同期,iBatis停止维护。 MyBatis是一种半自动化的Java持久层框架,其通过注解或XML 的方式将对象和SQL 关联起来。之所以说它是半自动的,是因为和Hibernate 等一些可自动生成SQL的ORM框架相比,使用MyBatis需要用户自行维护SQL,维护SQL 的工作比较繁琐,但也有好处。比如我们可控制SQL逻辑,可对其进行优化,以提高效率。
2. mybatis的核心部分
2.1 MyBatis配置XML文件的层次结构
<?xml version="1. 0" encoding="UTF-8"?>
<configuration> <!--配置 -->
<properties/> <!--属性-->
<settings/> <!--设置-->
<typeAliases/> <!--类型命名-->
<typeHandlers/> <!--类型处理器-->
<objectFactory/> <!--对象工厂-->
<plugins/> <!--插件-->
<environments> <!--配置环境-->
<environment> <!--环境变量 -->
<transactionManager/> <!--事务管理器-->
<dataSource/> <!-- 数据源-->
</environment>
</environments>
<databaseIdProvider/> <!--数据库厂商标识-->
<mappers/> <!--映射器-->
</configuration>
例举几个,不一一解释了
- properties是一个配置属性的元素,让我们能在配置文件的上下文中使用它。
- 别名(typeAliases) 是一个指代的名称。因为我们遇到的类全限定名过长,所以我们希望用一个简短的名称去指代它,而这个名称可以在MyBatis 上下文中使用。
- mappers常见有如下几种方法引入映射器
- 文件路径引入
- 包名引入
- 类注册引入
2.2 MyBatis的映射器
常见元素如下:
着重说一下resultMap吧,这也是mybtais里最复杂的元素,它的作用是定义映射规则,级联的更新,定制类型转化器。
<resultMap id="" type="">
<constructor></constructor>
<id></id> <!-- id代表resultMap的主键,而result代表其属性 -->
<result></result>
<association property=""></association> <!-- 一对一映射 -->
<collection property=""></collection> <!-- 一对多映射 -->
</resultMap>
constructor:constructor主要是用来配置构造方法,默认情况下mybatis会调用实体类的无参构造方法创建一个实体类,然后再给各个属性赋值,但是有的时候我们可能为实体类生成了有参的构造方法,并且也没有给该实体类生成无参的构造方法,这个时候如果不做特殊配置,resultMap在生成实体类的时候就会报错,因为它没有找到无参构造方法。
association 和 collection:是mybatis支持级联的一部分,我们知道在级联中有一对一、一对多、多对多等关系,association主要是用来解决一对一关系的,collection主要是用来解决一对多关系的
2.3 Mybtais操作案例
public class SqlSessionUtils {
private SqlSessionUtils(){}
// 配置文件
public static final String resource = "mybatis-config.xml";
/**
* SqlSession是通过SqlSessionFactory来构造的,相当于维护一个连接池,当我们不停的进行查询的时候, * 由于没有关闭连接,导致与数据库的连接数量达到了一个上限
*/
public static SqlSession getDefaultSqlSession() throws IOException {
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
return sqlSessionFactory.openSession();
}
/**
* SqlSessionManager通过动态代理技术+线程本地变量,升级了DefaultSqlSession的使用。
* 解决了DefaultSqlSession自动关闭和线程安全问题
* @return
* @throws IOException
*/
public static SqlSession getSqlSessionManage() throws IOException {
InputStream inputStream = Resources.getResourceAsStream(resource);
return SqlSessionManager.newInstance(inputStream);
}
}
@Test
public void testUpdateUserInfo() throws IOException {
SqlSession sqlSession = SqlSessionUtils.getDefaultSqlSession();
UserInfo userInfo = new UserInfo();
userInfo.setId(3);
userInfo.setUserName("测试修改");
userInfo.setPassword("111111");
userInfo.setRegDate(new Timestamp(Instant.now().toEpochMilli()));
// sqlSession.update("com.changda.mapper.UserInfoMapper.updateUserInfo");
UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
System.out.println(mapper.updateUserInfo(userInfo));
sqlSession.commit();
}
@Test
public void testUpdateUserInfo() throws IOException {
SqlSession sqlSession = SqlSessionUtils.getSqlSessionManage();
UserInfo userInfo = new UserInfo();
userInfo.setId(3);
userInfo.setUserName("测试修改");
userInfo.setPassword("111111");
userInfo.setRegDate(new Timestamp(Instant.now().toEpochMilli()));
UserInfoMapper mapper = sqlSession.getMapper(UserInfoMapper.class);
System.out.println(mapper.updateUserInfo(userInfo));
}
3.Mybatis中的Dao接口和XML文件里的SQL是如何建立关系的?
- 解析XML: 初始化SqlSessionFactoryBean会将mapperLocations路径下所有的XML文件进行解析
- 创建SqlSource: Mybatis会把每个SQL标签封装成SqlSource对象,可以为动态SQL和静态SQL
- 创建MappedStatement: XML文件中的每一个SQL标签就对应一个MappedStatement对象 ,并由 Configuration解析XML
- Dao接口代理: Spring中的FactoryBean 和 JDK动态代理返回了可以注入的一个Dao接口的代理对象
- 执行: 通过statement全限定类型+方法名拿到MappedStatement 对象,然后通过执行器Executor去执行具体SQL
四、SSM整合
第一步:导入相应的jar包
<properties>
<spring.version>5.1.8.RELEASE</spring.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- mybatis 包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--mybatis spring 插件 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!-- mysql连接 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>3.0-alpha-1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- slf4j日志包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
</dependencies>
第二步:写配置文件,将配置文件区分开
例举常见的一些xml配置,这里Spring3.0以后其实开始提倡JavaConfig的方式实现去XML配置,大家也不需要全部都记得,尤其Spring5.x版本之后,可以通过导入tomcat的内嵌jar包形式实现零xml配置启动,毕竟紧跟技术潮流嘛。
springmvc.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:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"
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 http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置IOC注解解析器 -->
<context:component-scan base-package="com.zl.controller" />
<!-- 配置MVC注解解析器 -->
<mvc:annotation-driven/>
<!-- 启动对@AspectJ注解的支持 -->
<aop:aspectj-autoproxy/>
<!-- 释放静态资源 -->
<mvc:default-servlet-handler/>
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置逻辑视图的前缀 -->
<property name="prefix" value="/views/" />
<!-- 配置逻辑视图的后缀 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>
</beans>
applicationContext-dao.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"
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">
<!-- 加载配置文件 -->
<context:property-placeholder location="classpath:jdbc.properties" />
<!-- 数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1"/>
<property name="minIdle" value="1"/>
<property name="maxActive" value="10"/>
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="10000"/>
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000"/>
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000"/>
<property name="testWhileIdle" value="true"/>
<!-- 这里建议配置为TRUE,防止取到的连接不可用 -->
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="false"/>
<!-- 添加此处作用是为了在SQL监控页面显示sql执行语句,不配置不显示 -->
<property name="filters" value="stat" />
</bean>
<!-- 配置 SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接池 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载 mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/sqlMapConfig.xml" />
<!-- 自动扫描mapping.xml文件 -->
<property name="mapperLocations" value="classpath:mapping/*.xml"></property>
</bean>
<!-- 配置 Mapper扫描 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 配置 Mapper扫描包 -->
<property name="basePackage" value="com.zl.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
</bean>
</beans>
application-service.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"
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">
<!-- 配置 service扫描 -->
<context:component-scan base-package="com.zl.service.impl" />
<!-- 配置 线程池 -->
<bean id="taskExecutor"
class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<property name="corePoolSize" value="5" />
<property name="maxPoolSize" value="10" />
<property name="WaitForTasksToCompleteOnShutdown" value="true" />
</bean>
<!-- 扫描切点类组件 -->
<context:component-scan base-package="com.zl.aop" />
</beans>
applicationContext-trans.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
</bean>
<!--事务增强-->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<!--事务属性定义-->
<tx:attributes>
<tx:method name="list*" read-only="true"/>
<tx:method name="get*" read-only="true"/>
<tx:method name="validate*" read-only="true"/>
<tx:method name="count*" read-only="true"/>
<tx:method name="insert*" propagation="REQUIRED" />
<tx:method name="delete*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<!-- 切面 匹配所有com.zl.service.impl包下的任意类和方法-->
<aop:config>
<aop:advisor advice-ref="txAdvice" pointcut="execution(* com.zl.service.impl.*.*(..))" />
</aop:config>
</beans>
第三步:配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>FruitSales</display-name>
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
<!-- 使用监听器加载 Spring配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 配置 spring -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext*.xml</param-value>
</context-param>
<!-- 配置 SrpingMVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
<!-- 标记容器在启动的时候就加载这个servlet -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- 配置所有以 /结尾的请求进入 SpringMVC -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- post乱码过滤器 -->
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
第四步:写测试用例
能看到helloWord就算搭建完成了
@Controller
public class UserInfoController {
@RequestMapping("/login")
public String login(){
System.out.println("helloword!");
return "index";
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/15204.html