勤奋勤劳铸梦成,
晨曦微露起长征。
汗水浇灌花似锦,
寒窗苦读岁月明。
千锤百炼心如铁,
万里征途志不倾。
持之以恒终有日,
功成名就笑谈中。
目录
接上文Java---SpringBoot详解一-CSDN博客
一,统一响应结果
之前我们返回的结果都是各自返回各自的,这样客户端解析的时候就非常麻烦,不便于封装,下面是我们想要的结果:
客户端只需要根据Result这一种格式解析就可以。
下面我们创建一个Result类:
java
package com.yuanzhen.yzjavatest.bean;
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 void setCode(Integer code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setData(Object data) {
this.data = data;
}
public Integer getCode() {
return code;
}
public String getMsg() {
return msg;
}
public Object getData() {
return 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 +
'}';
}
}
对我们之前写的controller代码进行改造:
java
@RestController
public class RequestController {
@RequestMapping("/yzTestBean")
public Result yzTestBean(User user){
System.out.println("user:"+user);
return Result.success(user);
}
@RequestMapping("/yzTestList")
public Result yzTestList(@RequestParam List<String> name){
System.out.println("name:"+name);
return Result.success(name);
}
@RequestMapping("/yzTestDate")
public Result yzTestDate(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime time){
System.out.println("time:"+time);
return Result.success(time);
}
@RequestMapping("/yzTestJson")
public Result yzTestJson(@RequestBody User user){
System.out.println("user:"+user);
return Result.success(user);
}
@RequestMapping("/yzTestPath/{name}")
public Result yzTestPath(@PathVariable String name){
System.out.println("name:"+name);
return Result.success(name);
}
}
然后使用postman进行访问,看看效果:
至此,我们就把请求响应结果进行了统一。
二,三层架构
先看下下面这段代码:
所有逻辑都在controller里面,这就导致controller这个类非常庞大,逻辑复杂,代码混乱。
因此,我们需要设计三层架构来解耦程序,是程序符合单一职责原则。
下面写个例子来体验一下三层架构的好处:
客户端发送姓名,服务端根据姓名查找具体用户信息,并将用户地址修改。
首先创建DAO层:
java
public interface IYZDao {
/*
* 根据用户姓名查找用户信息
* **/
User findUserByName(String name);
}
java
import com.yuanzhen.yzjavatest.dao.IYZDao;
public class YZDao implements IYZDao {
@Override
public User findUserByName(String name) {
User user = new User();
user.setName(name);
user.setAge(20);
Address address = new Address();
address.setProvince("北京");
address.setCity("北京");
user.setAddress(address);
return user ;
}
}
然后创建Service层:
java
public interface IYZService {
/**
* 处理用户信息
* */
User dealUser(String name);
}
java
public class YZService implements IYZService {
private YZDao yzDao =new YZDao();
@Override
public User dealUser(String name) {
User user = yzDao.findUserByName(name);
Address address = new Address();
address.setCity("淄博");
address.setProvince("山东");
user.setAddress(address);
return user;
}
}
最后改造controller层:
java
@RestController
public class RequestController {
private IYZService yzService = new YZService();
@RequestMapping("/yzTestPath/{name}")
public Result yzTestPath(@PathVariable String name){
User user = yzService.dealUser(name);
return Result.success(user);
}
}
postman运行结果:
这样就实现了三层架构。
三,分层解耦
刚才我们的代码存在一个问题,就是层与层之间存在耦合关系:
为了解耦,我们就不能通过直接创建对象的形式来实现,只能通过一个中间容器,将对象放到容器里面,需要的时候去容器里面取,这样就用到了控制反转和依赖注入:
下面我们将上面的demo修改为分层解耦的:
首先修改Dao层代码:
java
@Component //将当前容器交给IOC容器管理 成为IOC容器中的bean
public class YZDao implements IYZDao {
@Override
public User findUserByName(String name) {
User user = new User();
user.setName(name);
user.setAge(20);
Address address = new Address();
address.setProvince("北京");
address.setCity("北京");
user.setAddress(address);
return user ;
}
}
然后修改service层代码:
java
@Component //将当前容器交给IOC容器管理 成为IOC容器中的bean
public class YZService implements IYZService {
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private YZDao yzDao;
@Override
public User dealUser(String name) {
User user = yzDao.findUserByName(name);
Address address = new Address();
address.setCity("淄博");
address.setProvince("山东");
user.setAddress(address);
return user;
}
}
最后修改controller层代码:
java
@RestController
public class RequestController {
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private IYZService yzService;
@RequestMapping("/yzTestPath/{name}")
public Result yzTestPath(@PathVariable String name){
User user = yzService.dealUser(name);
return Result.success(user);
}
}
运行结果:
此时如果我们要实现一个新的service类:
java
@Component
public class YZService2 implements IYZService {
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private YZDao yzDao;
@Override
public User dealUser(String name) {
User user = yzDao.findUserByName(name);
Address address = new Address();
address.setCity("淄博111");
address.setProvince("山东111");
user.setAddress(address);
return user;
}
}
然后将原来的YZService从容器中拿出来:
java
//@Component //将当前容器交给IOC容器管理 成为IOC容器中的bean
public class YZService implements IYZService {
// @Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private YZDao yzDao;
@Override
public User dealUser(String name) {
User user = yzDao.findUserByName(name);
Address address = new Address();
address.setCity("淄博");
address.setProvince("山东");
user.setAddress(address);
return user;
}
}
只需要加两行注释就可以了。
运行结果:
这样就实现了分层解耦。
四,IOC
上面我们使用了Component注解,其实还有三个注解是项目中用的最多的:
五,DI
使用Primary
上面我们切换YZService2的时候,把YZService的注解注释掉了,其实还可以使用@Primary注解来处理:
将YZService的注解放开:
java
@Component //将当前容器交给IOC容器管理 成为IOC容器中的bean
public class YZService implements IYZService {
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private YZDao yzDao;
@Override
public User dealUser(String name) {
User user = yzDao.findUserByName(name);
Address address = new Address();
address.setCity("淄博");
address.setProvince("山东");
user.setAddress(address);
return user;
}
}
在YZService2上面添加Primary注解:
java
@Primary
@Component
public class YZService2 implements IYZService {
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private YZDao yzDao;
@Override
public User dealUser(String name) {
User user = yzDao.findUserByName(name);
Address address = new Address();
address.setCity("淄博111");
address.setProvince("山东111");
user.setAddress(address);
return user;
}
}
运行结果:
使用Qualifier
java
@RestController
public class RequestController {
@Qualifier("YZService2")
@Autowired //运行时,IOC容器会提供该类型的bean对象,并赋值给该变量 这就是依赖注入
private IYZService yzService;
@RequestMapping("/yzTestPath/{name}")
public Result yzTestPath(@PathVariable String name){
User user = yzService.dealUser(name);
return Result.success(user);
}
}
使用Resource:
java
@RestController
public class RequestController {
@Resource(name ="YZService2")
private IYZService yzService;
@RequestMapping("/yzTestPath/{name}")
public Result yzTestPath(@PathVariable String name){
User user = yzService.dealUser(name);
return Result.success(user);
}
}