相关链接
- Excel目录
- springboot-annotation on Gitee
目录
- springboot-annotation
- 〇、创建springboot项目
- 一、主程序类
- 1. @SpringBootApplication
- 二、Controller层(控制层)
- 2.1 类注解 TYPE
- 1. @Controller 注入ioc容器->controller层 ⭐️
- 2. @RequestMapping 映射->资源目录 ⭐️
- 3. @ResponseBody 后端 -> 浏览器 json对象⭐️
- 4. @CrossOrigin 解决跨域问题
- 2.2 方法注解 METHOD
- 1. @RequestMapping => 2.1.2 🚕
- 2. @CrossOrigin => 2.1.4 🚕
- 2.3 参数注解 PARAMETER
- 1. @RequestParam 获取 -> get请求参数 ⭐️
- 2. @RequestBody 浏览器 -> 后端 json数据(post请求)⭐️
- 3. @PathVariable 获取 -> restful风格请求参数
- 2.4 合并注解
- 1. @RestController 注入ioc容器->controller层⭐️
- 2. @GetMapping Get方式请求资源目录 ⭐️
- 3. @PostMapping Post方式请求资源目录⭐️
- 4. @PutMapping Put方式请求资源目录
- 5. @DeleteMapping Delete方式请求资源目录
- 6. @PatchMapping Patch方式请求资源目录
- 2.5 对比
- 1. @Controller 和 @RestController
- 2. @RequesetParam、@PathVariable、@RequestBody
- 3.@Get/Post/Put/Delete/Patch Mapping
- 三、Service层(服务层) (放入ioc)
- 3.1 类注解 TYPE
- 1. @Service 标记服务类->自动bean注册⭐️
- 2. @Component 标记组件类->自动bean注册⭐️
- 3. @Configuration 注入容器(手动) -> 自定义组件
- 3.2 方法注解 METHOD
- 1. @Bean 手动Bean注册
- 3.3 注解的注解 ANNOTATION_TYPE
- 1. @Bean => 3.2.1 🚕
- 3.4 对比
- 1. @Service --- @Component --- @Configuration + Bean
- 四、注入bean(从ioc取)
- 4.1 字段注解 FIELD
- 1. @Autowired 容器ioc->获取bean⭐️
- 2. @Resource 容器ioc->获取bean
- 3. @Qualifier 容器ioc->(获取时)指定bean
- 4.2 类注解 TYPE
- 1. @Resource => 4.1.2 🚕
- 2. @Qualifier => 4.1.3 🚕
- 4.3 方法注解 METHOD
- 1. @Autowired => 4.1.1 🚕
- 2. @Resource => 4.1.2 🚕
- 3. @Qualifier => 4.1.3 🚕
- 4.4 参数注解 PARAMETER
- 1. @Autowired => 4.1.1 🚕
- 1. @Qualifier => 4.1.3 🚕
- 4.5 构造器注解 CONSTRUCTOR
- 1. @Autowired => 4.1.1 🚕
- 4.6 注解的注解 ANNOTATION_TYPE
- 1. @Autowired => 4.1.1 🚕
- 2. @Qualifier => 4.1.3 🚕
- 4.6 对比
- 1. @Autowired --- @Autowired + @Qualifier --- @Resource
- 五、其他
- 1. @Alisfor 注解属性等价⭐️
- 2. @Value 从配置文件中取参数
- 六、lombok插件
- 6.1 类注解
- 1. @Data 实体类常用功能打包⭐️
- 2. @NoArgsConstructor 无参构造⭐️
- 3. @AllArgsConstructor 全参构造⭐️
- 4. @Getter get方法⭐️
- 5. @Setter set方法:star:
- 6.2 lombok失效问题
- 附录:springboot常见分层(AOP)
- 1. controller层 @Controller
- 2. service层 @Service
- 3. dao层(mapper层) @Repository
- 5. model层 @Data
- 6. common层
springboot-annotation
版本:
JDK:1.8
Spring:5.3.8
Springboot:2.5.2
lombok:1.16.10
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache/POM/4.0.0" xmlns:xsi="http://www.w3/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache/POM/4.0.0 https://maven.apache/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.springboot</groupId>
<artifactId>annotation</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>annotation</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--视图解析器 freemarker-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- SpringBoot中使用lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
注意: 不同版本之间注解会存在差异,例如@CrossOrigin注解
- @Component: 泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注;
- @Repository: 用于标注数据访问组件,即DAO组件;
- @Service: 用于标注业务层组件(业务逻辑);
- @Controller: 用于标注控制层组件(不包含业务逻辑);
- DispatcherServlet: 前端控制器 拦截前端所有请求:任务调度和分发;
- 映射器: Handler 配置的映射对象;
- 适配器: 通过ModelAndView寻找具体的处理器 Controller,以及Controller与前端进行数据交互;
- 视图解析器: 根据返回的逻辑视图找到对应的物理视图,并且将其封装成一个View对象,由视图渲染器进行视图的渲染最终展现给用户,有JSP,Volocity,或下面用到的 Freemarker;
〇、创建springboot项目
- Step1: New Project
- Step2: Spring Initializr
- Step3: wait
- Step4: Java version 8
- Step5: 导入依赖 Spring web
- Step7: Finish
- Step8: Wait (没有Maven的需要配置Maven,过程省略)
- Step9: Finish (默认端口8080)
- Step10: 解决pom.xml报红问题(不影响项目运行)
File -> Invalidate Caches / Restart... -> Invalidate and Restart
清除缓存并重启IDEA就可以解决
一、主程序类
1. @SpringBootApplication
@SpringBootApplication: 是Sprnig Boot项目的核心注解,目的是开启自动配置。包含以下三个@
@SpringBootConfiguration: 声明当前类是SpringBoot应用的配置类。
(项目中只能有一个,一般无需自己添加。)
@EnableAutoConfiguration: 开启自动配置。
告诉SpringBoot基于所添加的依赖,去"猜测"你想要如何配置Spring。
比如我们引入了spring-boot-starter-web,而这个启动器中帮我们添加了tomcat、SpringMVC的依赖,此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!我们使用SpringBoot构建一个项目,只需要引入所需框架的依赖,配置就可以交给SpringBoot处理了。
@ComponentScan: 配置组件扫描的指令。
提供了类似与<context:component-scan>标签的作用。通过basePackageClasses或者basePackages属性来指定要扫描的包。
如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包。而我们的@SpringBootApplication注解声明的类就是main函数所在的启动类。
因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。
二、Controller层(控制层)
2.1 类注解 TYPE
1. @Controller 注入ioc容器->controller层 ⭐️
a.作用域:
ElementType.TYPE:类、接口、枚举。
b.功能:
1. @Controller用于标记在一个类上,使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。
2. @Controller只是定义了一个控制器类,而使用@RequestMapping注解的方法才是处理请求的处理器。
c.参数:
value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController)
d.返回数据类型:
具体页面(比如*.html)
e.相关注解:
1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
2. 注解合并:@Controller + @ResponseBody = @RestController
3. 对比注解:@Controller 与 @RestController(2.5.1)
ViewController : 处理器
package com.springboot.annotation.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* @author GroupiesM
* @date 2021/07/06
* @introduction 1.controller注解相关的测试
*
* \@Controller 与 @RequestMapping
*/
@Controller
public class ViewController {
/**
* 不带数据直接返回页面
* @return String
*/
@RequestMapping("view")//url:http://localhost:8080/page/view
public String view() {
return "view.html";
}
}
view.html: 页面(必须放在图中为位置,否则读不到)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>视图页面</title>
</head>
<body>
<div>我的页面</div>
</body>
</html>
Step1: 使用浏览器访问 http://localhost:8080/view
Step2: 每次都写.html太麻烦了,在 application.properties 配置视图解析器(ViewResolver)前后缀
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
Step3: 再次访问http://localhost:8080/view
Step4: 上面都是不带数据只返回页面,下面要带数据返回 view.html 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>视图页面</title>
</head>
<body>
<div>我的页面</div>
<hr><div>${str1}</div>
<hr><div>${str2}</div>
</body>
</html>
Step5: 再次访问 http://localhost:8080/view
视图解析器: 常用的有 jsp、Volocity、Freemarker等。其中jsp视图解析器配置比较复杂,演示用freemarker解析比较方便
Step6: pom.xml 中引入freemarker(视图解析器,用来数据交互)
<!--视图解析器 freemarker-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
Step7: application.properteis配置freemarker
#spring视图解析器
##页面视图前缀
spring.mvc.view.prefix=/
##页面视图后缀
spring.mvc.view.suffix=.html
#freeMarker视图解析器
##后缀
spring.freemarker.suffix=.html
##指定资源(页面)默认路径,默认指向templates路径
spring.freemarker.template-loader-path=classpath:/static/
Step8: ViewController新增返回数据方法 dataview,并稍加改造
package com.springboot.annotation.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* @author GroupiesM
* @date 2021/07/06
* @introduction 1.controller注解相关的测试
*
* \@Controller 与 @RequestMapping
*/
@Controller
@RequestMapping("/page")
public class ViewController {
public static final String PAGE = "view";
/**
* 不带数据直接返回页面
* @return String
*/
@RequestMapping("/view")//url:http://localhost:8080/page/view
public String view(){
return PAGE;
}
/**
* 带数据的返回页面
* @return ModelAndView
*/
@RequestMapping("/dataview")//url:http://localhost:8080/page/dataview
public ModelAndView dataView(){
ModelAndView view = new ModelAndView(PAGE);
view.addObject("str1","我叫hello!");
view.addObject("str2","我是张三!");
return view;
}
}
Step10: 访问 http://localhost:8080/page/view
(不返回数据)
Step11: 访问 http://localhost:8080/page/dataview
(返回数据),成功解析
2. @RequestMapping 映射->资源目录 ⭐️
a.作用域:
1. ElementType.TYPE:类、接口、枚举;
2. ElementType.METHOD:方法。
b.功能:
配置http请求(url访问地址、请求方式、请求头等)。
c.参数:
1. name:为这个映射分配一个名称;
2. ⭐️value:映射的资源路径,与 path() 等价;
@RequestMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
@RequestMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
3. path:映射的资源路径,与 value() 等价;
4. method:要映射到http请求方法,共八种(GET、POST、HEAD、OPTIONS、PUT、PATCH、DELETE、TRACE);
5. params:映射的请求参数;
6. headers:映射的请求头;
7. consumes:映射的Content-type请求信格式,例如
consumes = “text/plain” => HTML格式
consumes = {“text/plain”, “application/"} => 纯文本格式
consumes = MediaType.TEXT_PLAIN_VALUE => ?
8. produces:映射的返回数据的类型以及编码;
produces = “text/plain” => HTML格式
produces = {“text/plain”, "application/”} => 纯文本格式
produces = MediaType.TEXT_PLAIN_VALUE => ?
produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)
d.相关注解:
1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
2. 注解合并:@RequestMapping可以使用在接口、类、枚举、方法上,@GETMapping、@POSTMapping等只能使用在方法上
REST模式:POST,GET,PUT,DELETE,PATCH的含义与区别
@RequestMapping(value = “user” , method = RequestMethod.GET) = @GetMapping(“user”)
@RequestMapping(value = “user” , method = RequestMethod.POST) = @PostMapping(“user”)
@RequestMapping(value = “user” , method = RequestMethod.PUT) = @PutMapping(“user”)
@RequestMapping(value = “user” , method = RequestMethod.DELETE) = @DeleteMapping(“user”)
@RequestMapping(value = “user” , method = RequestMethod.PATCH) = @PatchMapping(“user”)
映射资源目录示例(详细使用方法在2.1.1@Controller)
3. @ResponseBody 后端 -> 浏览器 json对象⭐️
a.作用域:
1. ElementType.TYPE:类、接口、枚举;
2. ElementType.METHOD:方法。
b.功能:
1. 将java对象转为json对象(下面示例中返回User实体类,自动解析为json)。
2. 将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
3. 表示该方法的返回结果直接写入 HTTP responsebody 中,一般在异步获取数据时使用(也就是AJAX)。
c.参数:
无
d.相关注解:
注解合并:@Controller + @ResponseBody = @RestController
User 实体类
package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
//private List<String> hobbies;
private String[] hobbies;//爱好
}
UserController 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author GroupiesM
* @date 2021/07/07
* @introduction 4.@RequestBody相关测试
*/
@Controller
public class UserController {
private static List<User> users = new ArrayList<>();
//静态代码块--存储用户信息
static {
users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
}
/**
* 查询用户
* @return
*/
@GetMapping("/get/user/a")//http://localhost:8080/get/user/a
public Object get() {
return users;
}
/**
* 查询用户,返回json对象 @ResponseBody
* @return
*/
@ResponseBody
@GetMapping("/get/user/b")//http://localhost:8080/get/user/b
public Object getUser() {
return users;
}
}
Postman请求java对象 (没有@ResponseBody) http://localhost:8080/get/user/a
Postman请求java对象 (添加@ResponseBody)http://localhost:8080/get/user/b
user对象转为json对象
4. @CrossOrigin 解决跨域问题
a.作用域:
1. ElementType.TYPE:类、接口、枚举;
2. ElementType.METHOD:方法。
b.功能:
1. 用于允许特定处理程序类和/或处理程序方法上的跨源请求(解决跨域问题)。
2. 需要在每个接口上添加此注解,或者统一使用过滤器进行配置,效果相同。
c.参数:
1.origins:允许可访问的域列表 @CrossOrigin(origins = "http://domain2")
;
2. ⭐️value:允许可访问的域列表,与 origins() 等价;
3. originPatterns:允许可访问的域列表,正则表达式,更加灵活;
4. allowedHeaders:允许访问的请求头列表,默认 allowedHeaders = {“*”};
1. *
表示允许所有请求头。
2. 允许访问的请求头在 响应首部(Access-Control-Allow-Headers) 的 预检请求(preflight request)中列出(没看懂)。
5. exposedHeaders:用户代理(user-agent)允许访问的响应头列表 => HTTP Headers
Cache-Control:?
Content-Language:?
Content-Type:指示服务器文档的MIME 类型。帮助用户代理(浏览器)去处理接收到的数据。
Expires:?
Last-Modified:?
Pragma:?
6. methods:支持的HTTP请求方法列表,默认与当前controller一致;
7. allowCredentials:默认情况下,标准的跨域请求是不会发送cookie等用户认证凭据的。打开后可以携带cookiec等信息。默认allowCredentials = “false”;
a. allowCredentials = “true” 表示对已配置域的高度信任,并通过公开特定于用户的敏感信息(如cookie和CSRF令牌),增加了web项目的攻击层面(attack surface)。
b. allowCredentials = “true” 时,远程服务器也要作相应的处理。在响应头那里设置 Access-Control-Allow-Credentials: true 。如果没有这个设置的话,浏览器就会报错。
c. allowCredentials = “true” 时,Access-Control-Allow-Origin不能设置为 *
8. maxAge:准备响应前的缓存持续的最大时间(秒),默认maxAge = -1;
d.名词解释:
跨域: 指的是浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的,是浏览器对javascript施加的安全限制。
同源策略:是指协议,域名,端口都要相同,其中有一个不同都会产生跨域;
跨域问题以及使用@CROSSORIGIN解决
注解@CrossOrigin解决跨域问题
UserController 处理器 添加@CrossOrigin
(表示来自本地8090端口的跨域请求可以访问以下两个资源 get 和 getUser)
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@Controller
public class UserController {
private static List<User> users = new ArrayList<>();
//静态代码块--存储用户信息
static {
users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
}
/**
* 查询用户
* @return
*/
@CrossOrigin(origins = "http://localhost:8090")
@GetMapping("/get/user/a")//http://localhost:8080/get/user/a
public Object get() {
return users;
}
/**
* 查询用户,返回json对象 @ResponseBody
* @return
*/
@ResponseBody
@CrossOrigin(origins = "http://localhost:8090")
@GetMapping("/get/user/b")//http://localhost:8080/get/user/b
public Object getUser() {
return users;
}
}
2.2 方法注解 METHOD
1. @RequestMapping => 2.1.2 🚕
2. @CrossOrigin => 2.1.4 🚕
2.3 参数注解 PARAMETER
1. @RequestParam 获取 -> get请求参数 ⭐️
a.作用域:
ElementType.PARAMETER:参数。
b.功能:
1. 用于将请求参数区域的数据映射到控制层方法的参数上。
2. 搭配@GetMapping使用,接收get请求 ?后面的参数。
3. 搭配@PostMapping使用,接收post请求?后面的参数。
4. 当请求中缺少某个参数时,默认为null,对于基本数据类型变量,则必须有值,如果允许空值,需要使用包装类声明;
c.参数:
1. name:请求的参数名,默认为接收参数的变量名;
2. ⭐️value:请求的参数名,默认为接收参数的变量名,与name()等价;
3. required:请求时该参数是否必传,默认required = true;
4. defaultValue:参数的默认值,支持SpEL表达式。默认defaultValue = ValueConstants.DEFAULT_NONE,因为不能在注解的属性中使用null来表示空值,所以用这段16位Unicode的字符串来表示空值,并且是不会发生这段字符串与用户定义的值是一样的情况。避免了用户给出的值却被当作是空值的情况(value = \n\t\t\n\t\t\n\uE000\uE001\uE002\n\t\t\t\t\n
时会被处理为null);
d.请求格式:
多个参数用&隔开: http://localhost:8080/param?id=1&type=苹果&discount=80%&price=3元
e.相关注解:
1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
2. 对比注解:@RequesetParam、@PathVariable、@RequestBody(2.5.2)
ParamController 处理器
package com.springboot.annotation.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
/**
* @author GroupiesM
* @date 2021/07/06
* @introduction 参数相关的测试
*/
@Controller
public class ParamController {
public static final String PAGE = "param";
@RequestMapping("/param")
public ModelAndView param(//必须传参
@RequestParam(value = "id") int id,
//可以不传参,但在类中要进行赋值,否则freeMarker解析页面时会报错
@RequestParam(value = "type", required = false) String type,
//可以不传参,取默认值
@RequestParam(value = "discount", required = false, defaultValue = "80%") String discount,
//可以不传参,取默认值
@RequestParam(value = "price",defaultValue = "5元") String price) {
//作用类似于上面 @RequestParam注解中的属性 defaultValue="苹果"
//不同的是 defaultValue会让required默认转为false
if (type == null) {
type = "苹果";
}
System.out.print("id = " + id);
System.out.print(" type = " + type);
System.out.print(" price = " + price);
System.out.println(" discount = " + discount);
ModelAndView view = new ModelAndView(PAGE);
view.addObject("id", id);
view.addObject("type", type);
view.addObject("price", price);
view.addObject("discount", discount);
return view;
}
}
param.html 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>参数测试</title>
</head>
<body>
<h2>${id}</h2>
<h2>${type}</h2>
<h2>${discount}</h2>
<h2>${price}</h2>
</body>
</html>
Step1: 编辑要访问的页面param.html
Step2: 接受请求参数的控制类ParamController
Step3: 获得浏览器提交的请求参数
Step4: 默认required = fasle(必须传参),get请求没有给id传值,导致报错;
Step5: 解决方式:RequstMapping添加属性 ,required = false(允许为空),defaultValue = 0(默认值为0,默认defaultValue = null,基本类型接收null也会报错);
Step6: 请求多个参数时(id,type,price,discount)的页面;
Step7: 请求参数不完整时,由于type值为null,会报错;
Step8: 可以在代码中给默认值,效果等类似 defaultValue(但例如基本数据类型int就不可以通过判断 == null进行赋值,所以不完全一样);
Step9: 测试正常传值的效果;
2. @RequestBody 浏览器 -> 后端 json数据(post请求)⭐️
a.作用域:
ElementType.PARAMETER:参数。
b.功能:
1. 用于将请求体区域的数据【前端返回json内容给后端】映射到控制层方法的参数【后端接收的是java对象(自定义entity)】上。
2. 搭配@PostMapping使用,接收post请求中,请求体携带的json字符串。
3. @RequestBody接收数据时,前端不能使用get方式提交数据(get方式没有请求体),而是用post方式进行提交。
c.参数:
required:该参数get请求时是否必传,默认required = true;
d.请求格式:
post -> body -> raw -> JSON
{
"id":66,
"name": "admin",
"gender": "男",
"age": 33,
"hobbies": [
"睡觉"
]
}
e.相关注解:
1. 常见组合:@Controller(类) + @RequestMapping(类) + @PostMapping(方法)+ @RequestBody(参数)
2. 对比注解:@RequesetParam、@PathVariable、@RequestBody(2.5.2)
User : 实体类
package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String[] hobbies;//爱好
}
UserRestController : 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserRestController {
private static List<User> users = new ArrayList<>();
private static List<User> returnUser;
//静态代码块--存储用户信息
static {users.add(new User(1, "张三", "男", 20,new String[]{"足球", "篮球"}))}
/**
* 新增数据,返回所有用户
* @param user
* @return
*/
@PostMapping("/post")//http://localhost:8080/user/post
public List<User> addUser(@RequestBody User user) {
users.add(user);
return users;
}
Postman请求示例:
3. @PathVariable 获取 -> restful风格请求参数
a.作用域:
ElementType.PARAMETER:参数。
b.功能:
1. 映射URL绑定的占位符。
2. 带占位符的URL是 Spring3.0 新增的功能,URL中的 {xxx} 占位符可以通过 @PathVariable(“xxx”) 绑定到操作方法的入参中。
c.参数:
1. name:请求的参数名,默认为接收参数的变量名;
2. ⭐️value:请求的参数名,默认为接收参数的变量名,与name()等价;
3. required:该参数请求时是否必传,默认required = true;
d.请求格式:
多个参数用&隔开: http://localhost:8080/param?1/苹果/0.8/3元
e.相关注解:
1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @PathVariable(参数)
2. 对比注解:@RequesetParam、@PathVariable、@RequestBody(2.5.2)
ParamController: 处理器
package com.springboot.annotation.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class ParamController {
public static final String PAGE = "param";
@RequestMapping("/param")
public ModelAndView param(//必须传参
@RequestParam(value = "id") int id,
//可以不传参,但在类中要进行赋值,否则freeMarker解析页面时会报错
@RequestParam(value = "type", required = false) String type,
//可以不传参,取默认值
@RequestParam(value = "discount", required = false, defaultValue = "80%") String discount,
//可以不传参,取默认值
@RequestParam(value = "price", defaultValue = "5元") String price) {
//作用类似于上面 @RequestParam注解中的属性 defaultValue="苹果"
//不同的是 defaultValue会让required默认转为false
if (type == null) {
type = "苹果";
}
System.out.print("id = " + id);
System.out.print(" type = " + type);
System.out.print(" price = " + price);
System.out.println(" discount = " + discount);
ModelAndView view = new ModelAndView(PAGE);
view.addObject("id", id);
view.addObject("type", type);
view.addObject("discount", discount);
view.addObject("price", price);
return view;
}
@RequestMapping("/param/{id}/{type}/{discount}/{price}")
public ModelAndView path(@PathVariable(required = false) int id,
@PathVariable(required = false) String type,
@PathVariable(required = false) String discount,
@PathVariable(required = false) String price) {
if (discount == null) {
discount = "80%";
}
if (price == null) {
price = "5元";
}
System.out.print("id = " + id);
System.out.println("type = " + type);
System.out.print(" price = " + price);
System.out.println(" discount = " + discount);
ModelAndView view = new ModelAndView(PAGE);
view.addObject("id", id);
view.addObject("type", type);
view.addObject("discount", discount);
view.addObject("price", price);
return view;
}
}
param.html: 页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>参数测试</title>
</head>
<body>
<h2>${id}</h2>
<h2>${type}</h2>
<h2>${discount}</h2>
<h2>${price}</h2>
</body>
</html>
Step1: 使用Path格式正常请求
Step2: 使用Path格式请求,带特殊符号%
Step3: 使用Path请求缺少参数时(没有映射缺少参数的URL地址)
Step4: 使用Path请求缺少参数时,需要先在Mapping中映射多个URL地址
2.4 合并注解
1. @RestController 注入ioc容器->controller层⭐️
a.作用域:
ElementType.TYPE:类、接口、枚举。
b.功能:
1. @RestController = @Controller + @Responsebody 等于同时了这添加两个注解。
2. @RestController 用于标记在一个类上,使用它标记的类就是一个SpringMvc Controller对象,分发处理器会扫描使用该注解的类的方法,并检测该方法是否使用了@RequestMapping注解。
3. 将Controller的方法返回的对象,通过 HttpMessageConverter 转换为指定格式后,写入到Response对象的body数据区。
4. 使用此注解此次请求将不再走视图处理器,而是直接将此响应结果写入到输入流中,其效果等同于使用response对象输出指定格式的数据(java对象转为json对象)。
c.参数:
1. ⭐️value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController),与 @Controller.value等价;
2. ⭐️Controller.value:与 @Component.value等价;
d.返回数据类型:
返回数据(对象,json,xml等)
e.相关注解:
1. 常见组合:@Restcontroller(类) + @RequestMapping(value = “/xxx”, produces = “application/json;charset=UTF-8”)(类) + @PostMapping(方法)+ @RequestBody(参数)
2. 注解合并:@Controller + @ResponseBody = @RestController
3. 对比注解:@Controller 与 @RestController(2.5.1)
Step1: @RestController返回数据 (返回一个String)
Step2: @RestController返回数据 (返回一个entity,entity通过HttpMessageConverter转为json对象)
使用Postman请求页面
Users 实体类: 修改用户属性
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String[] hobbies;//爱好
}
UserController 用户处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author GroupiesM
* @date 2021/07/07
* @introduction 3.RestController注解相关测试
*
* \@RestController 与 @GetMapping
*/
@RestController
@RequestMapping("user")
public class UserController {
private static List<User> users = new ArrayList<>();
private static List<User> returnUser;
//静态代码块--存储用户信息
static {
users.add(new User(1, "张三", "男", 20, new String[]{"足球","篮球"}));
users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
users.add(new User(3, "林青霞", "女", 22, new String[]{"唱歌","看电影"}));
}
@GetMapping("/get")//http://localhost:8080/user/get
public Object get() {
ArrayList<Object> arr = new ArrayList<>();
User user = new User(1, "张三", "男", 20, new String[]{"足球","篮球"});
System.out.println(user.toString());
return user;
}
//通过性别查找用户的方法(@RequestParam传参)
@GetMapping("/getbygender")//http://localhost:8080/user/getbygender
public static Object getByGenderA(@RequestParam(value = "gender") String gender) {
returnUser = new ArrayList<>();
for (User user : UserController.users) {
if (user.getGender().equals(gender)) {
returnUser.add(user);
}
}
System.out.println(returnUser);
return returnUser;
}
//通过性别查找用户的方法(@PathVariable传参)
@GetMapping("/getbygender/{gender}")//http://localhost:8080/user/getbygender
public static Object getByGenderB(@PathVariable("gender") String gender) {
returnUser = new ArrayList<>();
for (User user : UserController.users) {
if (user.getGender().equals(gender)) {
returnUser.add(user);
}
}
System.out.println(returnUser);
return returnUser;
}
}
Step3: 测试自定义功能,根据性别查询用户(@RequestParam格式)http://localhost:8080/user/getbygender?&gender=男
Step4: 测试自定义功能:根据性别查询用户(@PathVariable格式)`http://localhost:8080/user/getbygender/女``
2. @GetMapping Get方式请求资源目录 ⭐️
a.作用域:
ElementType.METHOD:方法。
b.功能:
1. 配置http请求(url访问地址、请求头等),指定请求方式为Get。
2. get请求一般用于信息获取,而且是安全的和幂等的 => 安全与幂等 。
c.参数:
1. name:为这个映射分配一个名称;
2. ⭐️value:映射的资源路径,与 path() 等价;
@GetMapping(“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
@GetMapping(“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
3. path:映射的资源路径,与 value() 等价;
5. params:映射的请求参数;
6. headers:映射的请求头;
7. consumes:映射的Content-type请求信格式,例如
consumes = “text/plain” => HTML格式
consumes = {text/plain", "application/*
} => 纯文本格式
consumes = MediaType.TEXT_PLAIN_VALUE => ?
8. produces:映射的返回数据的类型以及编码;
produces = “text/plain” => HTML格式
produces = {“text/plain”, “application/*”} => 纯文本格式
produces = MediaType.TEXT_PLAIN_VALUE => ?
produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)
d.相关注解:
1. 常见组合:@Controller(类) + @RequestMapping(类) + @GetMapping(方法)+ @RequestParam(参数)
2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.GET) = @GetMapping(“user”)
3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)
GetMapping部分源码:
User : 实体类
package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String[] hobbies;//爱好
}
UserController : 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
private static List<User> users = new ArrayList<>();
//静态代码块--存储用户信息
static {
users.add(new User(1, "张三", "男", 20,
new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21,
new String[]{"舞蹈"}));
users.add(new User(3, "林青霞", "女", 22,
new String[]{"唱歌", "看电影"}));
}
/**
* 查询用户
* @return
*/
@GetMapping(value = "/get")//http://localhost:8080/user/get
public List<User> get() {
return users;
}
Step1: POSTMAN请求 http://localhost:8080/user/get
3. @PostMapping Post方式请求资源目录⭐️
a.作用域:
ElementType.METHOD:方法。
b.功能:
1. 配置http请求(url访问地址、请求头等),指定请求方式为Post。
2. Post请求一般用于创建数据,不是安全和幂等的 => 安全与幂等 。
c.参数:
1. name:为这个映射分配一个名称;
2. ⭐️value:映射的资源路径,与 path() 等价;
@PostMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
@PostMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
3. path:映射的资源路径,与 value() 等价;
5. params:映射的请求参数;
6. headers:映射的请求头;
7. consumes:映射的Content-type请求信格式,例如
consumes = “text/plain” => HTML格式
consumes = {text/plain", "application/*
} => 纯文本格式
consumes = MediaType.TEXT_PLAIN_VALUE => ?
8. produces:映射的返回数据的类型以及编码;
produces = “text/plain” => HTML格式
produces = {“text/plain”, “application/*”} => 纯文本格式
produces = MediaType.TEXT_PLAIN_VALUE => ?
produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)
d.相关注解:
1. 常见组合:@Restcontroller(类) + @RequestMapping(value = “/xxx”, produces = “application/json;charset=UTF-8”)(类) + @PostMapping(方法)+ @RequestBody(参数)
2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.POST) = @PostMapping(“user”)
3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)
User : 实体类
package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String[] hobbies;//爱好
}
UserController : 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
private static List<User> users = new ArrayList<>();
//静态代码块--存储用户信息
static {
users.add(new User(1, "张三", "男", 20,
new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21,
new String[]{"舞蹈"}));
users.add(new User(3, "林青霞", "女", 22,
new String[]{"唱歌", "看电影"}));
}
/**
* 新增一个用户,返回所有用户列表
* @param user
* @return
*/
@PostMapping(value = "/post", produces = "application/json;charset=UTF-8")//http://localhost:8080/user/post
public List<User> addUser(@RequestBody User user) {
users.add(user);
return users;
}
Step1: Postman第一次请求 http://localhost:8080/user/post
请求方式: POST请求,Body -> raw -> json字符串
{
"id": 4,
"name": "张曼玉",
"gender": "女",
"age": 23,
"hobbies": [
"听音乐",
"做饭"
]
}
Step2: Postman第二次请求 http://localhost:8080/user/post
请求方式: POST请求,Body -> raw -> json字符串
{
"id": 5,
"name": "王祖贤",
"gender": "女",
"age": 24,
"hobbies": [
"睡觉"
]
}
4. @PutMapping Put方式请求资源目录
a.作用域:
ElementType.METHOD:方法。
b.功能:
1. 配置http请求(url访问地址、请求头等),指定请求方式为Put。
2. Put请求一般用于创建或完整更新数据,而且是安全和幂等的 => 安全与幂等 。
c.参数:
1. name:为这个映射分配一个名称;
2. ⭐️value:映射的资源路径,与 path() 等价;
@PutMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
@PutMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
3. path:映射的资源路径,与 value() 等价;
5. params:映射的请求参数;
6. headers:映射的请求头;
7. consumes:映射的Content-type请求信格式,例如
consumes = “text/plain” => HTML格式
consumes = {text/plain", "application/*
} => 纯文本格式
consumes = MediaType.TEXT_PLAIN_VALUE => ?
8. produces:映射的返回数据的类型以及编码;
produces = “text/plain” => HTML格式
produces = {“text/plain”, “application/*”} => 纯文本格式
produces = MediaType.TEXT_PLAIN_VALUE => ?
produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)
d.相关注解:
1. 常见组合:
2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.PUT) = @PutMapping (“user”)
3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)
无示例…
5. @DeleteMapping Delete方式请求资源目录
a.作用域:
ElementType.METHOD:方法。
b.功能:
1. 配置http请求(url访问地址、请求头等),指定请求方式为Delete。
2. Delete请求一般用于删除数据,而且是安全和幂等的 => 安全与幂等 。
c.参数:
1. name:为这个映射分配一个名称;
2. ⭐️value:映射的资源路径,与 path() 等价;
@DeleteMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
@DeleteMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
3. path:映射的资源路径,与 value() 等价;
5. params:映射的请求参数;
6. headers:映射的请求头;
7. consumes:映射的Content-type请求信格式,例如
consumes = “text/plain” => HTML格式
consumes = {text/plain", "application/*
} => 纯文本格式
consumes = MediaType.TEXT_PLAIN_VALUE => ?
8. produces:映射的返回数据的类型以及编码;
produces = “text/plain” => HTML格式
produces = {“text/plain”, “application/*”} => 纯文本格式
produces = MediaType.TEXT_PLAIN_VALUE => ?
produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)
d.相关注解:
1. 常见组合:@Restcontroller(类) + @RequestMapping(value = “/xxx”, produces = “application/json;charset=UTF-8”)(类) + @PostMapping(方法)+ @RequestBody(参数)
2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.DELETE) = @DeleteMapping(“user”)
3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)
User : 实体类
package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String[] hobbies;//爱好
}
UserController : 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
private static List<User> users = new ArrayList<>();
//静态代码块--存储用户信息
static {
users.add(new User(1, "张三", "男", 20,new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21,new String[]{"舞蹈"}));
users.add(new User(3, "林青霞", "女", 22,new String[]{"唱歌", "看电影"}));
}
/**
* 根据id删除对应User
* @param id
* @return
*/
@DeleteMapping(value = "/delete", produces = "application/json;charset=UTF-8")//http://localhost:8080/user/delete?id=3
public List<User> deleteUser(@RequestParam(value = "id") int id) {
Iterator<User> it = users.iterator();
while (it.hasNext()) {
User next = it.next();
if (next.getId() == id) {
it.remove();
}
}
return users;
}
}
Step1: Postman第一次请求 http://localhost:8080/user/delete?id=1
Step2: Postman第二次请求 http://localhost:8080/user/delete?id=2
Step3: Postman第三次请求 http://localhost:8080/user/delete?id=3
6. @PatchMapping Patch方式请求资源目录
a.作用域:
ElementType.METHOD:方法。
b.功能:
1. 配置http请求(url访问地址、请求头等),指定请求方式为Patch。
2. Patch请求一般用于更新部分数据,不是安全和幂等的 => 安全与幂等 。
c.参数:
1. name:为这个映射分配一个名称;
2. ⭐️value:映射的资源路径,与 path() 等价;
@PatchMapping (“/getusers”) 普通传参,使用@RequestParam或@RequestBody接收参数
@PatchMapping (“/getbyid/{id}”) restful风格传参,使用@PahVariable接收参数
3. path:映射的资源路径,与 value() 等价;
5. params:映射的请求参数;
6. headers:映射的请求头;
7. consumes:映射的Content-type请求信格式,例如
consumes = “text/plain” => HTML格式
consumes = {“text/plain”, “application/"} => 纯文本格式
consumes = MediaType.TEXT_PLAIN_VALUE => ?
8. produces:映射的返回数据的类型以及编码;
produces = “text/plain” => HTML格式
produces = {“text/plain”, "application/”} => 纯文本格式
produces = MediaType.TEXT_PLAIN_VALUE => ?
produces = “text/plain;charset=UTF-8” => HTML格式,编码UTF-8
produces = “application/json;charset=UTF-8” => JSON对象,编码UTF-8(返回json对象时一定要加这个,手动返回json字符串前端不能使用)
d.相关注解:
1. 常见组合:
2. 注解合并:@RequestMapping(value = “user” , method = RequestMethod.Patch) = @PutMapping (“user”)
3. 对比注解:@Get/Post/Put/Delete/Patch Mapping(2.5.3)
无示例…
2.5 对比
1. @Controller 和 @RestController
- @Controller
- 在对应的方法上,视图解析器可以解析return 的jsp,html页面
- 使用@Controller 这个注解,就不能返回JSON,XML或自定义mediaType内容到页面
- 适用场景:
跳转页面
- @RestController
- @RestController注解相当于@ResponseBody + @Controller
- 返回对象(String、Integer)、json(entity会自动转为json对象)、xml、自定义media Type给浏览器
- 使用@RestController这个注解,就不能返回jsp,html页面,视图解析器无法解析jsp,html页面
- 适用场景:
返回数据
2. @RequesetParam、@PathVariable、@RequestBody
@RequesetParam(“/xxx”)
http://localhost:8080/param?id=1&type=苹果&discount=80%&price=3元
@PathVariable(“/xxx/{param1}/{param2…}”)
http://localhost:8080/param/2/苹果/0.5/3元
(不能传特殊符号./\%#等
,=> 处理方式)
- 在后端的同一个接收方法里,@RequestBody与@RequestParam()可以同时使用,@RequestBody最多只能有一个,而@RequestParam()可以有多个。
- @RequestBody接收数据时,前端不能使用GET方式提交数据,而是用POST方式进行提交。
注解 | 支持类型 | 支持的请求类型 | 支持的Content-Type | 请求示例 | 默认值 |
---|---|---|---|---|---|
@RequestParam | url | Get | all | /orders?name=abc | √ |
Body | Post/Put/Delete/Patch | form-data,x-www.form-urlencoded | 见下图(Postman请求示例1) | ||
@RequestBody | Body | Post/Put/Delete/Patch | json | {"id":1,"name":"abc"}(Postman请求示例2) | × |
@PathVariable | url | Get | all | /orders/{id} | × |
Postman请求示例1:
Postman请求示例2:
3.@Get/Post/Put/Delete/Patch Mapping
REST模式:POST,GET,PUT,DELETE,PATCH的含义与区别
三、Service层(服务层) (放入ioc)
3.1 类注解 TYPE
1. @Service 标记服务类->自动bean注册⭐️
a.作用域:
ElementType.TYPE:类、接口、枚举。
b.功能:
1. 将ioc容器中指定的service对象放入spring ioc容器。
2. 在实现类上(Impl)加@Service注解,一个接口可以有多个实现类。
3. 一般按照以下方式分层使用。
1) service层:业务逻辑接口;
public interface UserService {
List<User> get();
}
2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service;
@Service
public class UserServiceImpl implements UserService{
public List<User> get(){...调用dao层查询User并return...};
}
&emsp ;3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/get")//http://localhost:8080/action/get
public List<User> get() {
return userService.get();
}
c.参数:
1. ⭐️value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController),与 @Component.value等价;
d.相关注解:
1. 常见组合:@Service(SerivceImpl中) + @Autowired(Controller中)
2. 对比注解:@Service — @Component — @Configuration + Bean(3.4.1)
具体用法参看@Autowired
2. @Component 标记组件类->自动bean注册⭐️
a.作用域:
ElementType.TYPE:类、接口、枚举。
d.相关注解:
@Service 和 @Component从功能角度来说效果相同,区别在于,按照约定使用在不同场合:
1. @Service标记的是服务层,只和需求相关,仅由Controller层调用
2. @Component标记的是组件(比如工具类),可以被Service,Controller等任何调用
3. @Configuration 注入容器(手动) -> 自定义组件
a.作用域:
ElementType.TYPE:类、接口、枚举。
b.功能:
被标记的类会被Spring扫描,该类中被@Bean注解的实例化方法,会放入ioc容器(手动Bean注册)
c.参数:
1. ⭐️value:指定注入ioc容器中的名称(Bean的id),如果不指定则默认为类名首字母小写(例如UserController -> userController),与 @Component.value等价;
d.相关注解:
1. 常见组合:@Configuration (类) + @Bean(方法)
2. 对比注解:@Service — @Component — @Configuration + Bean(3.4.1)
Step1: 手动创建一个MyBeans类,将需要注入ioc容器的方法用@Bean注解(具体使用方法查看3.4.1)
MyBeans: 自定义实体类,通过@Configuration+@BEan方式手动注入ioc容器
package com.springboot.annotation.cfg;
import com.springboot.annotation.impl.AdminServiceImpl;
import com.springboot.annotation.impl.UserServiceImpl;
import com.springboot.annotation.service.UserService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBeans {
/**手动注入spring ioc容器,指定对象名称admin
* @return AdminServiceImpl对象*/
@Bean
public UserService admin() {
return new AdminServiceImpl();
}
@Bean
public UserService user() {
return new UserServiceImpl();
}
}
UserService: 服务层接口
package com.springboot.annotation.service;
import com.springboot.annotation.entity.User;
import java.util.List;
public interface UserService {
List<User> get();
List<User> getByGenderB(String gender);
}
AdminServiceImpl: 服务层实现类1
package com.springboot.annotation.impl;
import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class AdminServiceImpl implements UserService {
private static List<User> users = new ArrayList<>();
private static List<User> returnUser;
//静态代码块--存储用户信息
static {
users.add(new User(1, "admin1", "男", 20, new String[]{"足球", "篮球"}));
users.add(new User(2, "admin2", "女", 21, new String[]{"舞蹈"}));
users.add(new User(3, "admin3", "女", 22, new String[]{"唱歌", "看电影"}));
}
/**
* 查询用户
* @return
*/
@Override
public List<User> get() {
return users;
}
/**
* 通过性别查找用户的方法(@PathVariable传参)
* @param gender
* @return
*/
@Override
public List<User> getByGenderB(String gender) {
returnUser = new ArrayList<>();
for (User user : users) {
if (user.getGender().equals(gender)) {
returnUser.add(user);
}
}
System.out.println(returnUser);
return returnUser;
}
}
UserServiceImpl: 服务层实现类2,与实现类1相比,查询的用户不同
package com.springboot.annotation.impl;
import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private static List<User> users = new ArrayList<>();
private static List<User> returnUser;
static {
users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
users.add(new User(3, "林青霞", "女", 22, new String[]{"唱歌", "看电影"}));
}
@Override
public List<User> get() {
return users;
}
@Override
public List<User> getByGenderB(String gender) {
returnUser = new ArrayList<>();
for (User user : users) {
if (user.getGender().equals(gender)) {
returnUser.add(user);
}
}
System.out.println(returnUser);
return returnUser;
}
}
UserActionController: 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/action")
public class UserActionController {
//使用MyBeans中手动注入ioc的对象
@Resource(name = "user")
private UserService userService;
@Resource(name = "admin")
private UserService adminService;
/**
* 查询user用户
* @return 当前所有用户
*/
@GetMapping("/getUser")//http://localhost:8080/action/getUser
public List<User> getUser() {
return userService.get();//
}
/**
* 查询admin用户
* @return 当前所有用户
*/
@GetMapping("/getAdmin")//http://localhost:8080/action/getAdmin
public List<User> getAdmin() {
return adminService.get();//
}
}
Step2: Postman请求实现类1 http://localhost:8080/action/getUser
按照如下顺序找到对应的实现类 UserServiceImpl(Service接口有两个实现类,返回内容不一样)
Step3: Postman请求实现类2 http://localhost:8080/action/getAdmin
按照如下顺序找到对应的实现类 AdminServiceImpl
Step4: 还可以通过@Autowired + @Qualifier组合使用来指定MyBeans中自定义的对象
3.2 方法注解 METHOD
1. @Bean 手动Bean注册
a.作用域:
1. ElementType.METHOD:方法。
2. ElementType.ANNOTATION_TYPE:注解。
b.功能:
手动注入ioc容器,指定实例化对象,和ioc容器中实例对象名称
3.3 注解的注解 ANNOTATION_TYPE
1. @Bean => 3.2.1 🚕
3.4 对比
1. @Service — @Component — @Configuration + Bean
@Service 和 @Component从功能角度来说效果相同,区别在于,按照约定使用在不同场合;
而@Configuration在功能上有一些差别了 => @Component和@Configuration作为配置类的差别:
1. @Service
1. 将实例化对象自动放入Spring ioc容器
2. 按照约定,@Service标记的是业务层,仅由Controller层调用
2. @Component
1. 将实例化对象自动放入Spring ioc容器
2. 按照约定,@Component标记的是组件类,可以被Service,Controller等任何调用
3. @Configuration + @Bean
1. 将实例化对象手动放入Spring ioc容器
2. 手动通过@Bean进行注册
MyBeans: 自定义实体类,通过@Configuration+@BEan方式手动注入ioc容器
@Configuration
public class MyBeans {
/**手动注入spring ioc容器,指定对象名称admin
* @return AdminServiceImpl对象*/
@Bean
public UserService admin() {
return new AdminServiceImpl();
}
@Bean
public UserService user() {
return new UserServiceImpl();
}
}
UserService: 服务层接口
package com.springboot.annotation.service;
import com.springboot.annotation.entity.User;
import java.util.List;
public interface UserService {
List<User> get();
List<User> getByGenderB(String gender);
}
AdminServiceImpl: 服务层实现类1
package com.springboot.annotation.impl;
import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class AdminServiceImpl implements UserService {
private static List<User> users = new ArrayList<>();
private static List<User> returnUser;
//静态代码块--存储用户信息
static {
users.add(new User(1, "admin1", "男", 20, new String[]{"足球", "篮球"}));
users.add(new User(2, "admin2", "女", 21, new String[]{"舞蹈"}));
users.add(new User(3, "admin3", "女", 22, new String[]{"唱歌", "看电影"}));
}
/**
* 查询用户
* @return
*/
@Override
public List<User> get() {
return users;
}
/**
* 通过性别查找用户的方法(@PathVariable传参)
* @param gender
* @return
*/
@Override
public List<User> getByGenderB(String gender) {
returnUser = new ArrayList<>();
for (User user : users) {
if (user.getGender().equals(gender)) {
returnUser.add(user);
}
}
System.out.println(returnUser);
return returnUser;
}
}
UserServiceImpl: 服务层实现类2,与实现类1相比,查询的用户不同
package com.springboot.annotation.impl;
import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class UserServiceImpl implements UserService {
private static List<User> users = new ArrayList<>();
private static List<User> returnUser;
static {
users.add(new User(1, "张三", "男", 20, new String[]{"足球", "篮球"}));
users.add(new User(2, "李四", "女", 21, new String[]{"舞蹈"}));
users.add(new User(3, "林青霞", "女", 22, new String[]{"唱歌", "看电影"}));
}
@Override
public List<User> get() {
return users;
}
@Override
public List<User> getByGenderB(String gender) {
returnUser = new ArrayList<>();
for (User user : users) {
if (user.getGender().equals(gender)) {
returnUser.add(user);
}
}
System.out.println(returnUser);
return returnUser;
}
}
UserActionController: 处理器
package com.springboot.annotation.controller;
import com.springboot.annotation.entity.User;
import com.springboot.annotation.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/action")
public class UserActionController {
//使用MyBeans中手动注入ioc的对象
@Resource(name = "user")
private UserService userService;
@Resource(name = "admin")
private UserService adminService;
/**
* 查询user用户
* @return 当前所有用户
*/
@GetMapping("/getUser")//http://localhost:8080/action/getUser
public List<User> getUser() {
return userService.get();//
}
/**
* 查询admin用户
* @return 当前所有用户
*/
@GetMapping("/getAdmin")//http://localhost:8080/action/getAdmin
public List<User> getAdmin() {
return adminService.get();//
}
}
请求接口1: Postman请求实现类1 http://localhost:8080/action/getUser
按照如下顺序找到对应的实现类 UserServiceImpl(Service接口有两个实现类,返回内容不一样)
请求接口2: Postman请求实现类2 http://localhost:8080/action/getAdmin
按照如下顺序找到对应的实现类 AdminServiceImpl
四、注入bean(从ioc取)
4.1 字段注解 FIELD
1. @Autowired 容器ioc->获取bean⭐️
a.作用域:
1. ElementType.FIELD:字段(包括枚举常量)。
2. ElementType.METHOD:方法。
3. ElementType.PARAMETER:参数。
4. ElementType.CONSTRUCTOR:构造器。
5. ElementType.ANNOTATION_TYPE:注解。
b.功能:
1. 自动按照类型注入。当使用注解注入属性时,set方法可以省略。它只能注入其他bean类型。当有多个类型匹配时。使用要注入的对象变量名称作为bean的id,在spring容器中查找,找到了注入成功,找不到就报错。
2. 将ioc容器中指定的service对象从ioc容器中取出。
3. 接口单个实现时,注入时加@Autowired 即可。
4. 接口多个实现时,注入时加@Autowired + @Qualifier配合使用(或者使用@Resource代替@Autowired,在参数name中指定bean的名称 ),指定具体的实现类。
5. 一般按照以下方式分层使用
1) service层:业务逻辑接口
public interface UserService {
List<User> get();
}
2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service
@Service
public class UserServiceImpl implements UserService{
public List<User> get(){...调用dao层查询User并return...};
}
3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/get")//http://localhost:8080/user/get
public List<User> get() {
return userService.get();
}
}
c.参数:
required:请求时该参数是否必传,默认required = true;
d.相关注解:
1. 常见组合:@Service(类-注入ioc)+ @Autowired(字段-从ioc取出Bean)
2. 注解合并:@Autowired + @Qualifier(“BeanId”) = @ Resource ( name = “BeanId” )
3. 对比注解:@Autowired — @Autowired + @Qualifier — @Resource (4.6.1)
场景1: @Autowired 注入Service,Service只有单个实现类
场景2: @Autowired 注入Service,Service有多个实现类(指定AdminServiceImpl
还是 UserServiceImpl
,不同实现类会返回不同处理结果)
场景3: 通过@Autowired + @Qualifier组合使用来指定@Configuration + @Bean 中的bean
2. @Resource 容器ioc->获取bean
a.作用域:
1. ElementType.TYPE:类、接口、枚举。
2. ElementType.FIELD:字段(包括枚举常量)。
3. ElementType.METHOD:方法。
b.功能:
1. 直接按照Bean的id注入。它也只能注入其他Bean类型。
2. name属性是指定Bean的id ,Bean的id是首字母小写的对象名。</font
3. 将ioc容器中指定的service对象(一个服务接口有多个实现时)从ioc容器中取出 。
4. 接口单个实现时,注入时加@Resource 即可。
5. 接口多个实现时,注入时加@Resource(name = “beanid”)(在参数name中指定bean的名称 ),指定具体的实现类。
6. 一般按照以下方式分层使用(不指定Bean id)
1) service层:业务逻辑接口
public interface UserService {
List<User> get();
}
2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service
@Service
public class UserServiceImpl implements UserService{
public List<User> get(){...调用dao层查询User并return...};
}
3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
@GetMapping("/get")//http://localhost:8080/user/get
public List<User> get() {
return userService.get();
}
}
7. (不指定Bean id)
1) service层:业务逻辑接口()
2) serviceimpl层:继承service,业务逻辑实现,并将impl实现类放入ioc容器 @service
@Service
public class UserServiceImpl implements UserService{...}
@Service
public class AdminServiceImpl implements UserService{...}
3) controller层:调用service方法,需要先将ioc容器中的 service对象从ioc容器中取出 ,需要指定Bean id,id为Bean对象的首字母小写。
@Resource(name = "userServiceImpl")
private UserService userService;
@Resource(name = "adminServiceImpl")
private UserService adminService;
c.参数:
1.⭐️name:指定从ioc容器中要取出的名称(Bean的id),默认为空。
2. lookup:
3. type:
4. authenticationType:
5. shareable:
6. mappedName:
7. description:对该资源的描述。该描述预计将使用部署应用程序的系统的默认语言。可以将描述呈现给部署人员,以帮助选择正确的资源。
d.相关注解:
1. 常见组合:@Service(多个类-注入ioc)+ @Resource( name = “BeanId” )
2. 注解合并:@Autowired + @Qualifier(“BeanId”) = @ Resource ( name = “BeanId” )
3. 对比注解:@Autowired — @Autowired + @Qualifier — @Resource (4.6.1)
3. @Qualifier 容器ioc->(获取时)指定bean
a.作用域:
1. ElementType.TYPE:接口、类、枚举。
2. ElementType.FIELD:字段(包括枚举常量)。
3. ElementType.METHOD:方法。
4. ElementType.PARAMETER:参数。
5. ElementType.ANNOTATION_TYPE:注解。
b.功能:
1. 在自动按照类型注入(@Autowired)的基础上,再按照Bean的id注入。它在给字段注入时不能单独使用
2. 必须和@Autowire一起使用;但是给方法参数注入时,可以单独使用。
3. value属性是指定Bean的id,Bean的id是首字母小写的对象名。
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
@Autowired
@Qualifier("adminServiceImpl")
private UserService adminService;
c.参数:
value:指定从ioc容器中要取出的名称(Bean的id),默认为空。
d.相关注解:
1. 常见组合:@Service(多个类-注入ioc)+ @Autowired(字段-从ioc取出Bean)+ @Qualifier(匹配到多个Bean实例时,指定Bean的id)
2. 注解合并:@Autowired + @Qualifier(“BeanId”) = @ Resource ( name = “BeanId” )
3. 对比注解:@Autowired — @Autowired + @Qualifier — @Resource (4.6.1)
4.2 类注解 TYPE
1. @Resource => 4.1.2 🚕
2. @Qualifier => 4.1.3 🚕
4.3 方法注解 METHOD
1. @Autowired => 4.1.1 🚕
2. @Resource => 4.1.2 🚕
3. @Qualifier => 4.1.3 🚕
4.4 参数注解 PARAMETER
1. @Autowired => 4.1.1 🚕
1. @Qualifier => 4.1.3 🚕
4.5 构造器注解 CONSTRUCTOR
1. @Autowired => 4.1.1 🚕
4.6 注解的注解 ANNOTATION_TYPE
1. @Autowired => 4.1.1 🚕
2. @Qualifier => 4.1.3 🚕
4.6 对比
1. @Autowired — @Autowired + @Qualifier — @Resource
1.使用语法不同: 当有注入Bean时有多个匹配类型,通过以下三种方式指定Bean的id
//写法1
@Autowired
@Qualifier("userServiceImpl")
private UserService userService;
@Autowired
@Qualifier("adminServiceImpl")
private UserService adminService;
//写法2
@Autowired
private UserServiceImpl userService;
@Autowired
private AdminServiceImpl adminService;
//写法3(建议此方式)
@Resource(name = "userServiceImpl")
private UserService userService;
@Resource(name = "adminServiceImpl")
private UserService adminService;
1. 使用语法不同: 当有注入Bean时只有单个匹配类型
//写法1
@Autowired
private UserService userService;
//写法2(建议此方式)
@Resource
private UserService userService;
2. 底层加载方式不同: => @Autowired 与@Resource的区别
五、其他
1. @Alisfor 注解属性等价⭐️
a.作用域:
ElementType.METHOD:方法。
b.功能:
可以使两个注解的属性互为别名(完全等价)。同一注解下可以指定任意两个注解,跨注解时表示两个注解的同名属性相等;(Alisfor标记的两个注解同时赋不同值时会报错)
c.备注:
等价的意思可以理解为多个属性(实例对象),但指向内存中同一地址
@Aliasfor源码:
场景1: 同注解中,两个属性等价
场景2: 跨注解时,两个同名属性等价(*.class只能是注解类)
场景3: 跨注解时,多个属性等价(*.class只能是注解类)
测试1: @RequestMapping的 只有一个属性时(仅有一个属性且为value时可以省略)
正常访问
测试2: @RequestMapping的 value 和 path属性相同时
正常访问
测试3: @RequestMapping的 value 和 path属性不同时
编译阶段不通过,启动项目时报错
2. @Value 从配置文件中取参数
a.作用域:
1. ElementType.FIELD:字段(包括枚举常量)。
2. ElementType.METHOD:方法。
3. ElementType.PARAMETER:参数。
4. ElementType.ANNOTATION_TYPE:注解。
b.功能:
从配置文件(application.properties)中取参数,注入基本数据类型和String类型数据。
application.properties: 添加配置参数
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.html
##freeMarker
#后缀
spring.freemarker.suffix=.html
#指定资源(页面)默认路径,默认指向templates路径
spring.freemarker.template-loader-path=classpath:/static/
#@Value相关测试
view.page=view
local.user.username=admin
local.user.password=123456
ValueController: 测试从配置文件中取值
package com.springboot.annotation.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author GroupiesM
* @date 2021/07/07
* @introduction @Value相关测试
*
*/
@RestController
@RequestMapping("/value")
public class ValueController {
@Value("${view.page}")
private String page;
@Value("${local.user.username}")
private String username;
@Value("${local.user.password}")
private String password;
@GetMapping("val")//localhost:8080/value/val
public String getValue() {
System.out.println(page + "..." + username + "..." + password);
return page + "..." + username + "..." + password;
}
}
Step1: 注意导包时选择springfreamwork包下的Value
Step2: 重启springboot项目,使用Postman访问接口,成功获取配置文件的值
六、lombok插件
SpringBoot - Lombok使用详解2(@Setter、@Getter、@ToString、@EqualsAndHashCode)
SpringBoot中lombok使用,自动生成getter、setter、构造器、toString()、equals()等
a. lombok简介
Lombok想要解决了的是在我们实体Bean中大量的Getter/Setter方法,以及toString, hashCode等可能不会用到,但是某些时候仍然需要复写,以期方便使用的方法;在使用Lombok之后,将由其来自动帮你实现代码生成,注意,其是 在运行过程中,帮你自动生成的 。就是说,将极大减少你的代码总量。
b. lombok作用
1. 消除模板代码
2. getter、setter、构造器、toString()、equals()
3. 便捷的生成比较复杂的代码,例如一个POJO要转化成构建器模式的形式,只需要一个注解。
c. 常用注解
1. @Data : 注解在类上, 为类提供@Getter、@Setter, 此外还提供了 equals()、hashCode()、toString() 方法
2. @NoArgsConstructor : 注解在类上, 为类提供无参构造
3. @AllArgsConstructor : 注解在类上, 为类提供全参构造
4. @Getter/@Setter : 注解在类上, 为类提供读写属
5. @ToString : 注解在类上, 为类提供 toString() 方法
6. @Slf4j : 注解在类上, 为类提供一个属性名为 log 的 log4j 的日志对象
7. @Log4j : 注解在类上, 为类提供一个属性名为 log 的 log4j 的日志对象
Step1: pom.xml添加lombok的jar包依赖(maven仓库)
<!-- https://mvnrepository/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.10</version>
</dependency>
Step2: 编写一个实体类 User,使用@Data注解
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private String name;
private int age;
}
Step2: 或者@Setter和@Getter(注意是lombok包下的Getter)
6.1 类注解
1. @Data 实体类常用功能打包⭐️
User: 实体类
package com.springboot.annotation.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor//全参构造
@NoArgsConstructor//无参构造
public class User {
private int id;//身份证
private String name;//姓名
private String gender;//性别
private int age;//年龄
private String[] hobbies;//爱好
}
TestUser: 编写测试方法,测试@Data是否起作用(测试了set方法和构造器)
@Test
public void TestUser(){
User user1 = new User();
user1.setName("AnyCode");
user1.setAge(20);
System.err.println(user.toString());
User user1 = new User("张三",30);
}
2. @NoArgsConstructor 无参构造⭐️
3. @AllArgsConstructor 全参构造⭐️
4. @Getter get方法⭐️
5. @Setter set方法⭐️
6.2 lombok失效问题
问题描述: 运行项目时会出现大量报错,原因是使用lombok的类中的get、set方法全部失效
报错类中都使用了lombok注解@Data,由于lombok注解失效,导致编译不通过
运行环境:
mac M1 2021版本
maven依赖(没有版本号,使用springboot版本下默认对应lombok版本)<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.4.5</version> <relativePath/> </parent> ... ... <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency>
问题解决: 1. Preference -> Build,Execution,Deployment -> Compiler -> Annotation Processors 勾选
- Enable annotation processing
问题解决: 2. 如果还是不能启动项目,继续修改下图位置 ,Preference -> Build,Execution,Deployment -> Compiler中添加配置 -Djps.track.ap.dependencies=false
附录:springboot常见分层(AOP)
备注: 这里的案例不涉及mybaties,没有和数据库交互查询数据的步骤,数据是在静态代码块中添加到userList中来模拟数据库课的;通常情况下Serviceimpl还需要调用dao层,dao层负责和数据库的交互;
测试1: 调用get方法 http://localhost:8080/action/get
测试2: 调用getbygender方法 http://localhost:8080/action/getbygender/男
1. controller层 @Controller
概述: controller层叫控制器层,负责前后端交互,接受前端请求,调用service层,接收service层返回的数据,最后返回具体的页面和数据到客户端。
不存放业务逻辑,通过调用Service层实现业务逻辑
2. service层 @Service
概述: service层叫业务逻辑层,存放业务逻辑处理,不直接对数据库进行操作,有接口和接口实现类,提供controller层调用的方法。
implService是接口的实现类,实现业务逻辑,impl通过@Service注解注入ioc容器
3. dao层(mapper层) @Repository
概述: dao层也叫mapper层,数据持久层,个人比较喜欢mapper层。
对数据库进行持久化操作,他的方法是针对数据库操作的,基本用到的就是增删改查。它只是个接口,只有方法名字,具体实现在mapper.xml中。
既然mapper层是直接与数据库相挂钩的,所以要先连接数据库。
可以在sqlMapConfig.xml文件或者application.properties文件里添加数据库属性等,如下所示:
sqlMapConfig.xml:添加属性
<!-- 加载属性文件 -->
<properties resource="/config/db.properties"></properties>
<!-- 和spring整合后environment配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
application.properties:添加属性
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123
5. model层 @Data
概述: model层也叫pojo层或者entity层。一般数据库的一张表对应一个pojo类,并且表中所有字段都在pojo类都一一对应。
1. POJO: Plain Ordinary Java Object 无规则简单Java对象。一个中间对象,可以转化为VO、DTO、PO。
2. VO: View Object 表示层对象。对应页面显示的数据对象,可以和表对应,也可以不对应。一般在Controller层使用。
3. DTO: Data Transfer Object 数据传输对象。传递数据。如PO有100个属性,页面VO只显示10个,那么DTO就也传输10个。一般在Service层使用。
4. PO: Persistent Object 持久化对象。它跟数据表形成一一对应的映射关系。一般在Dao层使用。
5. Entity: 实体,和PO的功能类似,和数据表一一对应,一个实体一张表。
6. common层
概述: 通用模块,不依赖其它任何模块,主要有utils
21/07/15
M
更多推荐
3.2.4_1 SpringBoot常用注解、lombok常用注解
发布评论