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 数据源(连接池)的作用
- 数据源(连接池)是提高程序性能的
- 事先实例化数据源,初始化部分连接资源
- 使用连接资源时从数据源中获取
- 使用完毕后将连接资源还给数据源 常见的数据源(连接池):
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配置文件,还需要使用注解替代的配置如下:
| 注解 | 说明 |
|---|---|
| @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执行流程
- 用户发请求至前端控制器
- 收到请求调用HandlerMapping处理器映射器
- 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给
- 调用处理器适配器
- 经过适配调用具体的处理器(,也叫后端控制器)
- 执行完返回
- 将执行结果返回给
- 将传给视图解析器
- 解析后返回具体
- 根据进行渲染视图(即将模型数据填充至视图中)。相应用户
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