目录
前言
自用笔记复盘,后续更新在javeweb03-mysql中
一、Maven(Maven官网)
Maven是apache旗下的一个开源项目,是一款用于管理和构建java项目的工具。
1.1 Maven作用
- 依赖管理:方便快捷的管理项目依赖的资源(jar包),避免版本冲突问题
- 统一项目结构:提供标准、统一的项目结构
- 项目构建:标准跨平台(Linux、Windows、MacOs)的自动化项目构建方式
1.2 Maven安装
注:在第2步中=》配置本地仓库可以自己指定一个文件里放入maven仓库,具体根据自己的存放路径有关。在写到conf里面的setting.xml文件里面
1.3 配置Maven环境
配置Maven环境(当前工程)
- 选择 IDEA中 File -->Settings --> Build,Execution,Deployment --> Build Tools --> Maven
- 设置 IDEA 使用本地安装的 Maven,并修改配置文件及本地仓库路径
注:建议使用下列的方法配置全局的maven
配置Maven环境(全局)
具体的做法跟上述图片中设置的大相径庭
1.4 创建Maven项目
- 创建模块,选择Maven,点击Next
- 填写模块名称,坐标信息,点击finish,创建完成
- 编写 HelloWorld,并运行
Maven坐标
什么是坐标?
- Maven 中的坐标是资源的唯一标识,通过该坐标可以唯一定位资源位置
- 使用坐标来定义项目或引入项目中需要的依赖。
Maven 坐标主要组成
- groupld:定义当前Maven项目隶属组织名称(通常是域名反写,例如:com.itheima)
- artifactld:定义当前Maven项目名称(通常是模块名称,例如 order-service、goods-service)
- version:定义当前项目版本号
1.5 导入Maven项目
方式一:打开IDEA,选择右侧Maven面板,点击+号,选中对应项目的pom.xml文件,双击即可
方式二:打开IDEA,选择右侧Maven面板,点击+号,选中对应项目的pom.xml文件,双击即可
二、依赖管理
2.1 依赖配置
依赖:指当前项目运行所需要的jar包,一个项目中可以引入多个依赖。
配置:
- 在 pom.xml中编写<dependencies>标签
- 在<dependencies>标签中 使用<dependency>引入坐标
- 定义坐标的 groupld,artifactld,version点击刷新按钮,引入最新加入的坐标
注意事项
如果引入的依赖,在本地仓库不存在,将会连接远程仓库/中央仓库,然后下载依赖。(这个过程会比较耗时,耐心等待)
2.2 依赖传递
依赖具有传递性
- 直接依赖:在当前项目中通过依赖配置建立的依赖关系
- 间接依赖:被依赖的资源如果依赖其他资源,当前项目间接依赖其他资源
排除依赖
排除依赖指主动断开依赖的资源,被排除的资源无需指定版本。
2.3 依赖范围
依赖的jar包,默认情况下,可以在任何地方使用。可以通过<scope>..</ scope>设置其作用范围。
作用范围:
- (main文件夹范围内)主程序范围有效。
- 测试程序范围有效。(test文件夹范围内)
- 是否参与打包运行。(package指令范围内)
scope值 主程序 测试程序 打包(运行) 范例 compile(默认) Y Y Y log4j test - Y - junit provided Y Y - servlet-api runtime - Y Y jdbc驱动
2.4 生命周期
Maven的生命周期就是为了对所有的maven项目构建过程进行抽象和统一
Maven中有3套相互独立的生命周期:
- clean:清理工作。
- default:核心工作,如:编译、测试、打包、安装、部署等。
- site:生成报告、发布站点等。
clean:
- pre-clean
- clen
- post-clean
default:
- validate
- initialize
- generate-sources
- process-sources
- generate-resources
- process-resources
- compile
- process-classes
- generate-test-sources
- process-test-sources
- generate-test-resources
- process-test-resources
- test-compile
- process-test-classes
- test
- prepare-package
- package
- verify
- install
- deploy
site:
- pre-site
- site
- post-site
- site-deploy
=====================================================================
- clean:移除上一次构建生成的文件
- compile:编译项目源代码
- test:使用合适的单元测试框架运行测试(junit)
- package:将编译后的文件打包,如:jar、war等
- install:安装项目到本地仓库
执行指定生命周期的两种方式
- 在idea中,右侧的maven工具栏,选中对应的生命周期,双击执行。
- 在命令行中,通过命令执行。 (具体的命令可以到网上自行查阅,这里就不放了)
三、web后端开发入门
3.1 SpringBootWeb入门
需求:使用 SpringBoot开发一个web应用,浏览器发起请求 /hello后,给浏览器返回字符串"Helo Word ~"
HelloController.class
package com.itheima.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; //请求处理类 @RestController public class HelloController { @RequestMapping("/hello") public String hello(){ System.out.println("hello world~"); return "hello world"; } }
在到主程序的spring自动创建的类中执行
package com.itheima; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootWebQuickstartApplication { public static void main(String[] args) { SpringApplication.run(SpringbootWebQuickstartApplication.class, args); } }
3.2 http
3.2.1 概述
概念:Hyper Text Transfer Protocol,超文本传输协议,规定了浏览器和服务器之间数据传输的规则。
特点:
基于TCP协议:面向连接,安全
基于请求-响应模型的:一次请求对应一次响应
HTTP协议是无状态的协议:对于事务处理没有记忆能力。每次请求-响应都是独立的
- 缺点:多次请求间不能共享数据,
- 优点:速度快
3.2.2 请求协议
- 请求行:请求数据第一行(请求方式、资源路径、协议)
- 请求头:第二行开始,格式key:value
- 请求体:POST请求,存放请求参数
Host | 请求的主机名 |
User-Agent | 浏览器版本,例如Chrome浏览器的标识类似Mozila/5.0.. Chrome/79,IE浏览器的标识类似Mozila/5.0(Windows NT ...) like Gecko |
Accept | 表示浏览器能接收的资源类型,如text/*,image/*或者*/*表示所有; |
Accept-Language | 表示浏览器偏好的语言,服务器可以据此返回不同语言的网页 |
Accept-Encoding | 表示浏览器可以支持的压缩类型,例如gzip,deflate等 |
Content-Type | 请求主体的数据类型 |
Content-Length | 请求主体的大小(单位:字节) |
请求方式-GET:请求参数在请求行中,没有请求体;如:/brand/findA11?name=oppo&status=1。GET请求大小是有限制的
请求方式-POST:请求参数在请求体中,POST请求大小是没有限制的。
3.2.3 响应协议
- 响应行:响应数据第一行(协议、状态码、描述)
- 响应头:第二行开始,格式key:value
- 响应体:最后一部分,存放响应数据
响应状态码:
1XX | 响应中-临时状态码,表示请求已经接收,告诉客户端应该继续请求或者如果它已经完成则忽略它 |
2XX | 成功-表示请求已经被成功接收,处理已完成。 |
3XX | 重定向-重定向到其他地方;让客户端再发起一次请求以完成整个处理 |
4XX | 客户端错误-处理发生错误,责任在客户端。如:请求了不存在的资源、客户端未被授权、禁止访问等 |
5XX | 服务器错误-处理发生错误,责任在服务端。如:程序抛出异常等。 |
常见的状态响应码:
状态码 | 英文描述 | 解释 |
---|---|---|
200 | OK | 客户端请求成功,即处理成功,这是我们最想看到的状态码 |
302 | Found | 指示所请求的资源已移动到由Location响应头给定的URL,浏览器会自动重新访问到这个页面 |
304 | Not Modified | 告诉客户端,你请求的资源至上次取得后,服务端并未更改,你直接用你本地缓存吧。隐式重定向 |
400 | Bad Request | 客户端请求有语法错误,不能被服务器所理解 |
403 | Forbidden | 服务器收到请求,但是拒绝提供服务,比如:没有权限访问相关资源 |
404 | Not Found | 请求资源不存在,一般是URL输入有误,或者网站资源被删除了 |
425 | Method Not Allowed | 请求方式有误,比如应该用GET请求方式的资源,用了POST |
428 | Precondition Required | 服务器要求有条件的请求。告诉客户端要想访问该资源,必须携带特定的请求头 |
429 | Too Many Requests | 指示用户在给定时间内发送了太多请求(“限速”),配合 Retry-Ater(多长时间后可以请求)响应头一起使用 |
431 | Request Header Fields TooLarge | 请求头太大,服务器不愿意处理请求,因为它的头部字段太大。请求可以在减少请求头域的大小后重新提交。 |
500 | Internal server Error | 服务器发生不可预期的错误。服务器出异常了,赶紧看日志去吧 |
503 | service unavailable | 服务器尚未准备好处理请求,服务器刚刚启动,还未初始化好 |
附:状态码大全https://cloud.tencent.com/developer/chapter/13553
Content-Type | 表示该响应内容的类型,例如text/html,application/json。 |
Content-Length | 表示该响应内容的长度(字节数) |
Content-Encoding | 表示该响应压缩算法,例如gzip。 |
Cache-Control | 指示客户端应如何缓存,例如max-age=300表示可以最多缓存300秒。 |
Set-Cookie | 告诉浏览器为当前页面所在的域设置cookie。 |
3.2.4 协议解析(略)
3.3 Tomcat
- 概念: Tomcat是Apache 软件基金会一个核心项目,是一个开源免费的轻量级Web服务器,支持Servlet/JSP少量JavaEE规范。
- JavaEE:Java Enterprise Edition,Java企业版。指lava企业级开发的技术规范总和。包含13项技术规范:JDBC、JNDI、EJBRMl、JSP、Servlet、XML、JMS、Java IDL、JTS、JTA、JavaMail、JAF
- Tomcat 也被称为 Web容器、Servlet容器。Servlet程序需要依赖于Tomcat才能运行
如何修改一些乱码问题:
常见的启动问题:
启动窗口一闪而过:检查JAVA HOME环境变量是否正确配置
端口号冲突:找到对应程序,将其关闭掉
HTTP协议默认端口号为80,如果将Tomcat端口号改为80,则将来访问Tomcat时,将不用输入端口号。
Tomcat 部署项目:
将项目放置到 webapps 目录下,即部署完成
入门程序解析
创建后自动下载一个压缩包,然后解压压缩包
3.4 请求响应
请求响应:
- 请求(HttpServletRequest):获取请求数据。
- 响应(HttpServletResponse):设置响应数据
- BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。
- CS架构:Client/Server,客户端/服务器架构模式。
3.4.1 请求项目创建
Postman是一款功能强大的网页调试与发送网页HTTP请求的Chrome插件。
作用:常用于进行接口测试
登录进来选择创建工作空间;注意:如果没有workspace请选注册并登录账户才可以看到
3.4.2 请求入门
保存请求的集合:
点击右上角的save按钮或者使用快捷键:ctrl+s
3.4.2 简单参数
@RequestParam中的reguired属性默认为true,代表该请求参数必须传递,如果不传递将报错。如果该参数是可选的,以将required属性设置为false。
1. 原始方式获取请求参数(了解)
- Controller方法形参中声明HttpServletRequest对象调用对象的getParameter(参数名)
2. SpringBoot中接收简单参数
- 请求参数名与方法形参变量名相同
- 会自动进行类型转换
3. @RequestParam注解
- 方法形参名称与请求参数名称不匹配,通过该注解完成映射该注解的required属性默认是true,代表请求参数必须传递
RequestController.class
package com.itheima.controller;
import com.itheima.pojo.User;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
/**
* 测试请求参数接收
*/
@RestController
//@Controller
//@ResponseBody
public class RequestController {
//
// 原始方式
// @RequestMapping("/simpleParam")
// public String simpleParam(HttpServletRequest request){
// //获取请求参数
// String name = request.getParameter("name");
// String ageStr = request.getParameter("age");
//
// int age = Integer.parseInt(ageStr);
// System.out.println(name+ ":" + age);
// return "OK";
// }
//
// springboot方式
@RequestMapping("/simpleParam")
// public String simpleParam(String name, Integer age){
System.out.println(name+ ":" + age);
return "OK";
}
//名称与请求名称不同
@RequestMapping("/simpleParam")
public String simpleParam(@RequestParam(name = "name", required = false) String username, Integer age){
System.out.println(username+ ":" + age);
return "OK";
}
}
3.4.3 实体参数
- 简单实体对象:请求参数名与形参对象属性名相同,定义POJ0接收即可
- 复杂实体对象:请求参数名与形参对象属性名相同,按照对象层次结构关系即可接收嵌套POJ0属性参数
简单实体
复杂实体
//2. 简单实体参数
@RequestMapping("/simplePojo")
public String simplePojo(User user){
System.out.println(user);
return "OK";
}
//复杂实体参数
@RequestMapping("/complexPojo")
public String complexPojo(User user){
System.out.println(user);
return "OK";
}
3.4.4 数组集合参数
- 数组参数:请求参数名与形参数组名称相同且请求参数为多个,定义数组类型形参即可接收参数
- 集合参数:请求参数名与形参集合名称相同且请求参数为多个,@RequestParam 绑定参数关系
//3. 数组集合参数
@RequestMapping("/arrayParam")
public String arrayParam(String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
}
@RequestMapping("/listParam")
public String listParam(@RequestParam List<String> hobby){
System.out.println(hobby);
return "OK";
}
3.4.5 日期时间参数
日期参数:使用 @DateTimeFormat 注解完成日期参数格式转换
//4. 日期时间参数
@RequestMapping("/dateParam")
public String dateParam(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime updateTime){
System.out.println(updateTime);
return "OK";
3.4.6 Json参数
JSON参数:JSON数据键名与形参对象属性名相同,定义POJ0类型形参即可接收参数,需要使用 @RequestBody标识
{
"name":"张三",
"age":18,
"address":{
"province":"北京",
"city":"北京"
}
}
//5. json参数
@RequestMapping("/jsonParam")
public String jsonParam(@RequestBody User user){
System.out.println(user);
return "OK";
}
3.4.7 路径参数
路径参数:通过请求URL直接传递参数,使用!.1来标识该路径参数,需要使用 @PathVariable 获取路径参数
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id , @PathVariable String name){
System.out.println(id);
System.out.println(name);
return "OK";
}
多个参数
@RequestMapping("/path/{id}/{name}")
public String pathParam2(@PathVariable Integer id , @PathVariable String name){
System.out.println(id);
System.out.println(name);
return "OK";
}
3.4.8 响应数据
@ResponseBody
- 类型:方法注解、类注解
- 位置:Controller方法上/类上
- 作用:将方法返回值直接响应,如果返回值类型是 实体对象/集合,将会转换为JSON格式响应说明:@RestController = @Controller + @ResponseBody ;
响应字符串
@RequestMapping("/hello")
public String hello() {
System.out.println("Hello World ~");
return "Hello World ~";
}
响应对象json
@RequestMapping("/getAddr")
public Address getAddr() {
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
return addr;
}
响应集合
@RequestMapping("/listAddr")
public List<Address> listAddr() {
List<Address> list = new ArrayList<>();
Address addr = new Address();
addr.setProvince("广东");
addr.setCity("深圳");
Address addr2 = new Address();
addr2.setProvince("陕西");
addr2.setCity("西安");
list.add(addr);
list.add(addr2);
return list;
}
Result.class
package com.itheima.pojo; /** * 统一响应结果封装类 */ public class Result { private Integer code ;//1 成功 , 0 失败 private String msg; //提示信息 private Object data; //数据 date public Result() { } public Result(Integer code, String msg, Object data) { this.code = code; this.msg = msg; this.data = data; } public Integer getCode() { return code; } public void setCode(Integer code) { this.code = code; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } public Object getData() { return data; } public void setData(Object data) { this.data = data; } public static Result success(Object data){ return new Result(1, "success", data); } public static Result success(){ return new Result(1, "success", null); } public static Result error(String msg){ return new Result(0, msg, null); } @Override public String toString() { return "Result{" + "code=" + code + ", msg='" + msg + '\'' + ", data=" + data + '}'; } }
对应响应代码:
@RequestMapping("/hello") public Result hello() { System.out.println("Hello World ~"); //return new Result(1,"success","Hello World ~"); return Result.success("Hello World ~"); } @RequestMapping("/getAddr") public Result getAddr() { Address addr = new Address(); addr.setProvince("广东"); addr.setCity("深圳"); return Result.success(addr); } @RequestMapping("/listAddr") public Result listAddr() { List<Address> list = new ArrayList<>(); Address addr = new Address(); addr.setProvince("广东"); addr.setCity("深圳"); Address addr2 = new Address(); addr2.setProvince("陕西"); addr2.setCity("西安"); list.add(addr); list.add(addr2); return Result.success(list); }
Springboot项目的静态资源(html,css,js等前端资源)默认存放目录为:classpath:/static、classpath:/public、classpath:/resou
EmpController.class
package com.itheima.controller; import com.itheima.pojo.Emp; import com.itheima.pojo.Result; import com.itheima.utils.XmlParserUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class EmpController { @RequestMapping("/listEmp") public Result list(){ //1. 加载并解析emp.xml String file = this.getClass().getClassLoader().getResource("emp.xml").getFile(); System.out.println(file); List<Emp> empList = XmlParserUtils.parse(file, Emp.class); //2. 对数据进行转换处理 - gender, job empList.stream().forEach(emp -> { //处理 gender 1: 男, 2: 女 String gender = emp.getGender(); if("1".equals(gender)){ emp.setGender("男"); }else if("2".equals(gender)){ emp.setGender("女"); } //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导 String job = emp.getJob(); if("1".equals(job)){ emp.setJob("讲师"); }else if("2".equals(job)){ emp.setJob("班主任"); }else if("3".equals(job)){ emp.setJob("就业指导"); } }); //3. 响应数据 return Result.success(empList); } }
XmlParserUtils.classpackage com.itheima.utils; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; public class XmlParserUtils { public static <T> List<T> parse(String file , Class<T> targetClass) { ArrayList<T> list = new ArrayList<T>(); //封装解析出来的数据 try { //1.获取一个解析器对象 SAXReader saxReader = new SAXReader(); //2.利用解析器把xml文件加载到内存中,并返回一个文档对象 Document document = saxReader.read(new File(file)); //3.获取到根标签 Element rootElement = document.getRootElement(); //4.通过根标签来获取 user 标签 List<Element> elements = rootElement.elements("emp"); //5.遍历集合,得到每一个 user 标签 for (Element element : elements) { //获取 name 属性 String name = element.element("name").getText(); //获取 age 属性 String age = element.element("age").getText(); //获取 image 属性 String image = element.element("image").getText(); //获取 gender 属性 String gender = element.element("gender").getText(); //获取 job 属性 String job = element.element("job").getText(); //组装数据 Constructor<T> constructor = targetClass.getDeclaredConstructor(String.class, Integer.class, String.class, String.class, String.class); constructor.setAccessible(true); T object = constructor.newInstance(name, Integer.parseInt(age), image, gender, job); list.add(object); } } catch (Exception e) { e.printStackTrace(); } return list; } }
emp.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>员工信息</title> </head> <link rel="stylesheet" href="element-ui/index.css"> <script src="./js/vue.js"></script> <script src="./element-ui/index.js"></script> <script src="./js/axios-0.18.0.js"></script> <body> <h1 align="center">员工信息列表展示</h1> <div id="app"> <el-table :data="tableData" style="width: 100%" stripe border > <el-table-column prop="name" label="姓名" align="center" min-width="20%"></el-table-column> <el-table-column prop="age" label="年龄" align="center" min-width="20%"></el-table-column> <el-table-column label="图像" align="center" min-width="20%"> <template slot-scope="scope"> <el-image :src="scope.row.image" style="width: 80px; height: 50px;"></el-image> </template> </el-table-column> <el-table-column prop="gender" label="性别" align="center" min-width="20%"></el-table-column> <el-table-column prop="job" label="职位" align="center" min-width="20%"></el-table-column> </el-table> </div> </body> <style> .el-table .warning-row { background: oldlace; } .el-table .success-row { background: #f0f9eb; } </style> <script> new Vue({ el: "#app", data() { return { tableData: [] } }, mounted(){ axios.get('/listEmp').then(res=>{ if(res.data.code){ this.tableData = res.data.data; } }); }, methods: { } }); </script> </html>
emp.xml
<?xml version="1.0" encoding="UTF-8" ?> <emps> <emp> <name>金毛狮王</name> <age>55</age> <image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/1.jpg</image> <!-- 1: 男, 2: 女 --> <gender>1</gender> <!-- 1: 讲师, 2: 班主任 , 3: 就业指导 --> <job>1</job> </emp> <emp> <name>白眉鹰王</name> <age>65</age> <image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/2.jpg</image> <gender>1</gender> <job>1</job> </emp> <emp> <name>青翼蝠王</name> <age>45</age> <image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/3.jpg</image> <gender>1</gender> <job>2</job> </emp> <emp> <name>紫衫龙王</name> <age>38</age> <image>https://web-framework.oss-cn-hangzhou.aliyuncs.com/web/4.jpg</image> <gender>2</gender> <job>3</job> </emp> </emps>
3.5 分层解耦
3.5.1 三层架构
- controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据
- service:业务逻辑层,处理具体的业务逻辑。
- dao:数据访问层(Data Access 0bject)(持久层),负责数据访问操作,包括数据的增、删、改、查。
EmpController.class
package com.itheima.controller; import com.itheima.pojo.Emp; import com.itheima.pojo.Result; import com.itheima.service.EmpService; import com.itheima.service.impl.EmpServiceA; import com.itheima.utils.XmlParserUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController public class EmpController { private EmpService empService = new EmpServiceA(); @RequestMapping("/listEmp") public Result list(){ //1. 调用service, 获取数据 List<Emp> empList = empService.listEmp(); //3. 响应数据 return Result.success(empList); } // @RequestMapping("/listEmp") // public Result list(){ // //1. 加载并解析emp.xml // String file = this.getClass().getClassLoader().getResource("emp.xml").getFile(); // System.out.println(file); // List<Emp> empList = XmlParserUtils.parse(file, Emp.class); // // //2. 对数据进行转换处理 - gender, job // empList.stream().forEach(emp -> { // //处理 gender 1: 男, 2: 女 // String gender = emp.getGender(); // if("1".equals(gender)){ // emp.setGender("男"); // }else if("2".equals(gender)){ // emp.setGender("女"); // } // // //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导 // String job = emp.getJob(); // if("1".equals(job)){ // emp.setJob("讲师"); // }else if("2".equals(job)){ // emp.setJob("班主任"); // }else if("3".equals(job)){ // emp.setJob("就业指导"); // } // }); // // //3. 响应数据 // return Result.success(empList); // } }
EmpDao.interface
package com.itheima.dao; import com.itheima.pojo.Emp; import java.util.List; public interface EmpDao { //获取员工列表数据 public List<Emp> listEmp(); }
EmpDaoA.class
package com.itheima.dao.ipml; import com.itheima.dao.EmpDao; import com.itheima.pojo.Emp; import com.itheima.utils.XmlParserUtils; import java.util.List; public class EmpDaoA implements EmpDao { @Override public List<Emp> listEmp() { //1. 加载并解析emp.xml String file = this.getClass().getClassLoader().getResource("emp.xml").getFile(); System.out.println(file); List<Emp> empList = XmlParserUtils.parse(file, Emp.class); return empList; } }
EmpService.interface
package com.itheima.service; import com.itheima.pojo.Emp; import java.util.List; public interface EmpService { //获取员工列表 public List<Emp> listEmp(); }
EmpServiceA.class
package com.itheima.service.impl; import com.itheima.dao.EmpDao; import com.itheima.dao.ipml.EmpDaoA; import com.itheima.pojo.Emp; import com.itheima.service.EmpService; import java.util.List; public class EmpServiceA implements EmpService { private EmpDao empDao = new EmpDaoA(); @Override public List<Emp> listEmp() { //1. 调用dao, 获取数据 List<Emp> empList = empDao.listEmp(); //2. 对数据进行转换处理 - gender, job empList.stream().forEach(emp -> { //处理 gender 1: 男, 2: 女 String gender = emp.getGender(); if ("1".equals(gender)) { emp.setGender("男"); } else if ("2".equals(gender)) { emp.setGender("女"); } //处理job - 1: 讲师, 2: 班主任 , 3: 就业指导 String job = emp.getJob(); if ("1".equals(job)) { emp.setJob("讲师"); } else if ("2".equals(job)) { emp.setJob("班主任"); } else if ("3".equals(job)) { emp.setJob("就业指导"); } }); return empList; } }
3.5.2 分层解耦
- 内聚:软件中各个功能模块内部的功能联系。
- 耦合:衡量软件中各个层/模块之间的依赖、关联的程度。
- 软件设计原则:高内聚低耦合。
控制反转:
- Inversion Of Control,简称I0C。对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转
依赖注入:
- DependencyInjection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为bean
3.5.3 IOC与DI
3.5.3.1 入门
3.5.3.2 IOC详解
要把某个对象交给IOC容器管理,需要在对应的类上加上如下注解之一
注解 | 说明 | 位置 |
---|---|---|
@Component | 声明bean的基础注解 | 不属于以下三类时,用此注解 |
@Controller | @Component的衍生注解 | 标注在控制器类上 |
@Service | @Component的行生注解 | 标注在业务类上 |
@Repository | @Component的行生注解 | 标注在数据访问类上(由于与mybatis整合,用的少) |
这里我自己总结了一下:就是controller(加@controller)层《=service(加@service)层中的数据《=dao层(加@repository),同时需要
在对应赋值的属性上添加@autowired
一层一层的套用,这就是内聚和解耦的合并
注意事项:
- 声明bean的时候,可以通过value属性指定bean的名字,如果没有指定,默认为类名首字母小写(一般不用)
- 使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller。
Bean组件扫描
前面声明bean的四大注解,要想生效,还需要被组件扫描注解@ComponentScan扫描。
- @Componentscan注解虽然没有显式配置,但是实际上已经包含在了启动类声明注解
- @SpringBootApplication中,默认扫描的范围是启动类所在包及其子包。
3.5.3.3 DI详解
Bean注入
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报出如下错误
通过以下几种方案来解决:
- @Primary
- @Qualifier
- @Resource