一、三层架构
(一)基础
在请求响应中,将代码都写在controller中,看起来内容很复杂,但是复杂的代码总体可以分为:数据访问、逻辑处理、接受请求和响应数据三个部分。在程序中我们尽量让一个类或者一个方法只有一个功能,这就是单一职责原则。增强可读性和可扩展性,减少代码复杂性。为此将三层架构分为controller(接受请求、相应数据),Service(逻辑处理),Dao(数据访问)。
- Controller:控制层,接收前端发送的请求,对请求进行处理,并响应数据。
- Service:业务逻辑层,处理具体的业务逻辑。
- Dao:数据访问层(Data Access Object)(持久层),负责数据访问操作,包括数据的增删改查。
(二)实例拆分
以javaweb_06:请求响应——响应 中的四、实例为例,将其拆分为三部分,首先为实现service和dao分别创建接口,然后分别实现其接口。
controller原本的代码:
@RequestMapping("/listEmp")
public Result list(){
//1、加载并解析emp.xml文件
String file = this.getClass().getClassLoader().getResource("emp.xml").getFile();
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
//2、对数据进行转化(那么就需要遍历)处理 gender和job
empList.stream().forEach(emp -> {
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);
}
1、拆分结构
2、创建接口
EmpDao.java
package org.example.dao;
import org.example.pojo.Emp;
import java.util.List;
public interface EmpDao {
//获取员工列表数据
public List<Emp> listEmp();
}
EmpService.java
package org.example.service;
import org.example.pojo.Emp;
import java.util.List;
public interface EmpService {
public List<Emp> listEmp();
}
3、实现接口
创建对应的类实现接口中定义的方法:
EmpDaoA.java
package org.example.dao.impl;
import org.example.dao.EmpDao;
import org.example.pojo.Emp;
import org.example.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();
List<Emp> empList = XmlParserUtils.parse(file, Emp.class);
return empList;
}
}
EmpServiceA.java
package org.example.service.impl;
import org.example.dao.EmpDao;
import org.example.dao.impl.EmpDaoA;
import org.example.pojo.Emp;
import org.example.service.EmpService;
import java.util.List;
public class EmpServiceA implements EmpService {
public EmpDao empDao = new EmpDaoA();
@Override
public List<Emp> listEmp() {
//1、调用dao获取数据
List<Emp> empList = empDao.listEmp();
//2、对数据进行转化(那么就需要遍历)处理 gender和job
empList.stream().forEach(emp -> {
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;
}
}
修改EmpController.java
package org.example.controller;
import org.example.pojo.Emp;
import org.example.pojo.Result;
import org.example.service.EmpService;
import org.example.service.impl.EmpServiceA;
import org.example.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);
}
}
二、分层解耦
内聚:软件中各个功能模块内部的功能联系
耦合:衡量软件中各个层/模块之间的依赖关系、关联的程度。
控制反转:Inversion Of Control 简称IOC,对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转。
依赖注入:Dependency Injection,简称DI。容器为应用程序提供运行时,所依赖的资源,称之为依赖注入。
Bean对象:IOC容器中创建、管理的对象,称之为bran。
三、IOC&DI入门
1、控制反转
Service层及Dao层的实现类交给IOC容器管理。
2、依赖注入
为Controller及Service注入运行时依赖的对象。
3、运行测试
四、IOC详解
1、Bean的声明
从Conponent衍生出三类,分别管理每一层,如果对象由不由这三层管理,但是还想交给IOC容器直接管理,才直接由Conponent注解。
注:
①声明bean的时候,可以通过Value属性指定bean的名字,如果没有指定,默认类名首字母小写.
②使用以上四个注解都可以声明bean,但是在springboot集成web开发中,声明控制器bean只能用@Controller.
2、bean的组件扫描
①之前声明得bean的四大注解,想要生效,还需要被组件扫描注解@ComponenetScan扫描
②@ComponentScan注解虽然没有显式配置,但是实际上已经包含了启动类声明注解@SpringBootApplication中,默认扫描的范围是启动类所在的包及其子包。
五、DI详解
1、bean注入:
@Autowired注解,默认是按照类型进行,如果存在多个相同类型的bean,将会报错。
解决方法:
@Primary:设置bean的优先级,想要谁先生效就将该注释加在它之前
@Qualifier:在@Autowired注解之后加上@Qualifier(“想要生效的名字”)
@Resource:不使用@Autowired,而是换成@Resource(name=“指定的名字”)
2、@Resource与@Autowired的区别
①@Autowired是Spring框架提供的注解,而@Resource是JDK提供的注解。
②@Autowired默认按照类型注入,而@Resource默认按照名称注入