Spring & SpringMVC & MyBatis
一、Spring的体系结构
自下往上:
- Test
- Core Container 核心容器
- Beans :容器
- Core :核心
- Context :上下文
- spEL :Spring表达式
- AOP----Aspects----Instrumentation----Messaging
- Data Access/Integration 数据访问层
- JDBC
- ORM
- OXM
- JMS
- Transactions
- Web
- WebSocket
- Servlet
- Web
- Portlet
二、一般创建流程
- 导入坐标
- UserDao接口
- UserDaolmpl实现
- applicationContext.xml 创建配置文件,将当前文件配置到配置文件()
- Application文件 getBean(" {id} ")获取对象
三、Spring配置文件
3.1 Bean标签的基本配置
- id 唯一标识 不允许重复
- class 路径 全限定名
注意点: Bean内部存在无参构造
3.2 Bean标签范围配置
scope
取值范围 | 说明 | 生命周期 |
---|---|---|
singleton | 默认的,单例的 | 对象创建:应用加载,创建容器时对象就被创建了 对象运行:只要容器在,对象一直活着 对象销毁:当应用卸载,销毁容器时,对象就被销毁了 |
prototype | 多例的 | 对象创建:当使用对象时,创建新的对象实例 对象运行:只要对象在使用中,就一直活着 对象销毁:当对象长时间不用时,被Java的垃圾回收器回收了 |
request | WEB项目中,Spring创建一个Bean的对象,将对象存到request域中 | |
session | WEB项目中,Spring创建一个Bean的对象,将对象存到session域中 | |
global session | WEB项目中,应用在Portlet环境中,如果没有Portlet环境,那么globalSession相当于session |
3.3 Bean生命周期配置
- init-method 指定类中的初始化方法名称
- destroy-method 指定类中销毁方法名称
3.4 Bean实例化三种方式
- 无参构造方法 Important
- 工厂静态方法实例化 factory-method
- 工厂实例方法实例化 配两个Bean 写工厂类 类中方法返回实例化值
<bean id="factory" class="com.ithemima.factory.DynamicFactory"></bean>
<bean id="userDao" factory-bean="factory" factory-method="getUserDao" ></bean>
3.5 Bean的依赖注入
set方法 Service内部需要Dao 需要文件配置
<bean>
<property name="userDao" ref="" value="" ></property>
(u大小转成小写 对应Service中setUserDao)
(ref 对象类型引用)
(value 普通数据类型)
</bean>
如果是集合类型 以 List<String>
为例
<bean>
<property>
<list>
<value>xxx</value>
<value>xxx</value>
</list>
</property>
</bean>
Map<String, Object>
<bean>
<property>
<Map>
<entry key="" value-ref="{Bean的id}"></entry>
</Map>
</property>
</bean>
3.6 知识要点
Spring的重点配置 文档
内容 | 含义 |
---|---|
<bean> |
标签 |
id属性 | 在容器中Bean实例的唯一标识,不允许重复 |
class属性 | 要实例化的Bean的全限定名 |
scope属性 | Bean的作用范围,常用是Singleton(默认)和prototype |
<proterty> 属性 |
属性注入 |
name属性 | 属性名称 |
value属性 | 注入的普通属性值 |
ref属性 | 注入的对象引用值 |
<list> |
标签 |
<Map> |
标签 |
<properties> |
标签 |
<constructor-arg> |
有参构造注入 |
<import> 标签 |
导入其他的Spring的分文件 |
四、Spring相关API
4.1 ApplicationContext的实现类
- ClassPathXmlApplicationContext 从类的根路径(resource)下加载配置文件
- FileSystemXmlApplicationContext 从磁盘路径上加载配置文件,配置文件可以在磁盘的任意位置
- AnnotationConfigApplicationContext 使用注解配置容器对象时,需要使用此类来创建Spring容器,它用来读注解
4.2 getBean()方法使用
- 传一个
String
类型数据 id 可以获取相同类型的数据 - 传一个
<T>
如xxx.class 返回值为该类 不能获取多个相同类型的数据
4.3 知识要点
Spring的重点API
ApplicationContext app = new ClasspathXmlApplicationContext("xml文件");
app.getBean("id");
app.getBean(Class);
Spring配置数据源
1.1 数据源(连接池)的作用
- 数据源(连接池)是提高程序性能的
- 事先实例化数据源,初始化部分连接资源
- 使用连接资源时从数据源中获取
- 使用完毕后将连接资源还给数据源
常见的数据源(连接池):DBCP、C3P0、BoneCP、Druid
1.2 数据源的开发步骤
- 导入数据源的坐标和数据库驱动坐标
- 创建数据源对象
- 设置数据源的基本连接数据
- 使用数据源获取连接资源和归还资源
1.3 数据源的手动创建
pom中 dependencies配置
ComboPoolDataSource dataSource = new ComboPoolDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/");
dataSource.setUser("root");
dataSource.setPassword("root");
Connection connection = dataSource.getConnection();//连接数据源
connection.close();//归还数据源
解耦合 读取配置文件
ResourceBundle = ResourceBundle.getBundle("jdbc");//resource下jdbc.properties文件
String driver = rb.getString("jdbc.driver");//Key
String url = rb.getString("jdbc.url");
String username = rb.getString("jdbc.username");
String password = rb.getString("jdbc.password");
ComboPoolDataSource dataSource = new ComboPoolDataSource();
dataSource.setDriverClass(driver);
dataSource.setJdbcUrl(url);
dataSource.setUser(username);
dataSource.setPassword(password);
Connection connection = dataSource.getConnection();//连接数据源
connection.close();//归还数据源
1.4 Spring 配置数据源
先配置
ApplicationContext app = new ApplicationCOntext();
DataSource dataSource = app.getBean(DataSource.class);
Connection connection = dataSource.getConnection();
connection.close();
1.5 知识要点
Spring容器加载properties文件
<context:property-placeholder location="xx.properties"></context:property-placeholder>
<property name="" value="${key}" />
Spring注解开发
2.1 Spring原始注解
Spring原始注解主要是替代的配置 文档
注解 | 说明 |
---|---|
@Component | 使用在类上实例化Bean |
@Controller | 使用在Web层类上用于实例化Bean |
@Service | 使用在service层类上用于实例化Bean |
@Repository | 使用在dao层类上用于实例化Bean |
@Autowired | 使用在字段上用于根据类型依赖注入 |
@Qualifier | 结合@Autowired一起使用,用于根据名称进行依赖注入 |
@Resource | 相当于@Autowired+@Qualifier,按照名称进行注入 |
@Value | 注入普通属性 |
@Scope | 标注Bean的作用范围 |
@PostConstruct | 使用在方法上标注该方法是Bean的初始化方法 |
@PreDestroy | 使用在方法上标注该方法是Bean的销毁方法 |
注意: | |
使用注解进行开发时,需要在applicationContext.xml中配置组件扫描,作用是指定哪个包及其子包下的Bean需要进行扫描以便识别使用注解配置的类、字段和方法 |
<context:component-scan base-package=""></context:component-scan>
2.2 Spring新注解 文档
使用上面的注解还不能全部替代xml配置文件,还需要使用注解替代的配置如下:
- 非自定义的Bean配置 (如第三方规定的)
- 加载properties文件的配置
- 组件扫描的配置
- 引入其他文件的配置
注解 | 说明 |
---|---|
@Configuration | 用于指定当前类是一个Spring配置类,当创建容器时会从该类上加载注解 |
@ComponentScan | 用于指定Spring在初始化容器时要扫描的包 作用和在Spring的xml配置文件中的 <context:component-scan base-package="com.itheima"/> 一样 |
@Bean | 使用在方法上,标注将该方法的返回值存储到Spring容器中 |
@PropertySource | 用于加载.properties 文件中的配置 |
@Import | 用于导入其他配置类 |
2.3 使用Junit进行测试
2.4 Spring监听器
Spring提供了一个监听器ContextLoaderListener,对获取上下文功能进行封装,该监听器
内部加载Spring配置文件,创建应用上下文对象,并存储到ServletContext域中,提供了一个客户端工具WebApplicationContextUtils供使用者获得应用上下文对象
SpringMVC
SpringMVC快速入门
需求:客户端发起请求,服务器端接受请求,执行逻辑并进行视图跳转
开发步骤:
- 导入SpringMVC相关坐标
- 配置SpringMVC核心控制器DispathcerServlet
- 创建Controller类和视图页面
- 使用注解配置Controller类中业务方法的映射地址
- 配置SpringMVC核心文件spring-mvc.xml
- 客户端发起请求测试
流程:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4yXtMMR1-1632051628434)(C:\Users\Superclass\IdeaProjects\demo01\src\main\resources\SpingLearn\SpringMVC.jpg “SpringMVC”)]
SpringMVC执行流程
- 用户发请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping处理器映射器
- 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
- DispatcherServlet调用HandlerAdapter处理器适配器
- HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)
- Controller执行完返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewResolver视图解析器
- ViewResolver解析后返回具体View
- DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。DispatcherServlet相应用户
SpringMVC注解
@RequestMapping
作用:用于建立请求URL和处理请求方法之间的对应关系
位置:
- 类上,请求URL的第一级访问目录,此处不写的话,就相当于应用的根目录
- 方法上,请求URL的第二级访问目录,与类上的使用@RequestMapping标注的一级目录一起组成虚拟访问路径
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController{
//访问路径为 http://localhost:8080/user/save
@RequestMapping("/save")
public String save(){
return "/success.jsp"; //注意需要`/` 否则路径为相对路径会找不到资源
}
}
属性:
- value 用于指定请求的URL,它和path属性的作用是一样的
- method 用于指定请求的方式(四种,但是
form
只能回get/post
) - params 用于指定限制请求参数的条件。它支持简单的表达式。要求请求参数的key和value必须和配置的一模一样
SpringMVC知识要点
SpringMVC相关组件
- 前端控制器 DispatcherServlet
- 处理器映射器 HandlerMapping
- 处理器适配器 HandlerAdapter
- 处理器 Handler
- 视图解析器 ViewResolver
- 视图 View
SpringMVC注解和配置
- 请求映射注解 @RequestMapping
- 视图解析器配置
REDIRECT_URL_PREFIX="redirect:"
FORWARD_URL_PREFIX="forward:"
prefix="";
suffix="";
SpringMVC数据响应
1.1 SpringMVC的数据响应方式
1) 页面跳转
- 直接返回字符串
- 通过ModelAndView对象返回
2) 回写数据 - 直接返回字符串
- 返回对象或集合
1.2 页面跳转
1. 返回字符串形式
@RequestMapping("/quick")
public String quickMethod(){
return "index";
}
<!--配置内部资源视图解析器-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views" /> <!--路径前缀-->
<property name="suffix" value=".jsp" /> <!--路径后缀-->
</bean>
转发地址 /WEB-INF/views/index.jsp
2. 返回ModelAndView对象
@RequestMapping("/quick")
public ModelAndView quickMethod(){
/*
* Model: 模型 作用:封装数据
* View: 视图 作用:展示数据
*/
ModelAndView modelAndView = new ModelAndView();
//设置模型数据
modelAndView.addObject("username","itcast"); //任意数据
//设置视图
modelAndView.setViewName("index");
return modelAndView;
}
参数为ModelAndView
@RequestMapping("/quick2")
public ModelAndView quickMethod(ModelAndView modelAndView){
//注入
/*
* Model: 模型 作用:封装数据
* View: 视图 作用:展示数据
*/
//设置模型数据
modelAndView.addObject("username","itcast"); //任意数据
//设置视图
modelAndView.setViewName("index");
return modelAndView;
}
ModelAndView可以拆开,单取Model
1.3 回写数据
1. 直接返回字符串
Web基础阶段,客户端访问服务器端,如果想直接回写字符串作为响应体返回的话,只需要使用response.getWriter().print("Hello World");
即可,
那么在Controller中想直接回写字符串该怎样呢?
@RequestMapping("/quick3")
public void save(HttpServletResponse response) throws IOException {
//回写
response.getWriter().print("hello itcast");
}
如何解耦合
需要@ResponseBody
注解告知SpringMVC框架,方法返回的字符串不是跳转,是直接在http响应体中返回
@RequestMapping("/quick3")
@ResponseBody //回写就要加
public void save(){
return "hello itcast";
}
如何返回json数据
@RequestMapping("/quick3")
@ResponseBody //回写就要加
public void save(){
User user = new User();
user.setUsername("李四");
user.setAge(30);
ObjectMapper objectMapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(user);
return json;
}
手动转很累
2. 返回对象或集合
<!--配置处理器映射器 RequestMappingHandlerAdapter -> messageConverters -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
<property name="messageConverters">
<list> <!--内部方法为 public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters)-->
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <!-- 2=to -->
</bean>
</list>
</property>
</bean>
@RequestMapping("/quick3")
@ResponseBody //回写就要加
public User save(){
//利用[适配器]
user.setUsername("李四");
user.setAge(30);
return user;
}
可以使用mvc的注解驱动代替上述xml配置
<!--mvc的注解驱动-->
<mvc:annotation-driven xmlns="http://www.springframework.org/schema/cache"></mvc:annotation-driven>
1.4 知识要点
- 直接页面跳转
- 直接返回字符串 --视图跳转
forward:
转发redirect
重定向
- 返回ModelAndView对象返回
- Model 数据模型
- View 视图
- 回写数据
- 直接返回字符串
- 返回对象或集合
SpringMVC获取请求数据
1. 获取请求参数
客户端请求参数的格式是: name=value&name=value...
即GET
服务器端要获取请求的参数,有时还需要进行数据的封装,SpringMVC可以接受接收如下类型的参数:
- 基本类型参数
- POJO类型参数
- 数组类型参数
- 集合类型参数
2.获得基本类型参数
Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配
@RequestMapping("/quick4")
@ResponseBody //回写就要加
public void userParams(String name, int age){
System.out.println(name);
System.out.println(age);
}
3.获得POJO类型参数
Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配
@RequestMapping("/quick5")
@ResponseBody
public void userParams(User user){
System.out.println(user);
}
4.获取数组类型参数
Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射
@RequestMapping("/quick5")
@ResponseBody
public void userParams(String[] strs){
System.out.println(Arrays.asList(strs));
}
5.获得集合类型参数
获得集合参数时,要将集合参数包装到一个POJO中才可以
当使用ajax提交时,可以指定contenttype为json形式,那么在方法参数位置使用@RequestBody
可以直接接收集合数据而无需使用POJO进行包装
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
<script>
var userList = new Array();
userList.push({
username:"张三",age:18});
userList.push({
username:"李四",age:20});
$.ajax({
type:"POST",
url:"${pageContext.request.contextPath}/user/quick6",
data:JSON.stringify(userList),
contentType:"application/json;charset=utf-8"
});
</script>
</head>
<body>
</body>
</html>
import org.springframework.web.bind.annotation.ResponseBody;
@RequestMapping("/quick6")
@ResponseBody
public void userParams(@ResponseBody List < User > userList)throws IOException{
System.out.println(userList);
}
mvc配置
<!--开发资源的访问-->
<mvc:resources mapping="/js/**" location="/js/"/>
或者
<mvc:default-servlet-handler/>
6.请求数据乱码问题
当POST请求时,数据会出现乱码,我们可以设置一个过滤器来进行编码的过滤
配置filter
<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>
7.参数绑定注解@requestParam
当请求的参数名称与Controller的业务方法名称不一致时,就需要通过@RequestParam注解显示的绑定
<form action="${pagaContext.request.contextPath}/test" method="post">
<input type="text" name=