Fork me on GitHub

JackLin的博客

当前位置:首页 > 标签

SpringBoot 14 Spring 2 SpringMVC 3 MyBatis 2 Linux 4 阿里云 13 宝塔 1 Docker 3 ElasticSearch 2 Redis 4 Shiro 0 Dubbo 0 Swagger 0 Thymeleaf 6 数据库 11 MySQL 11 外键 2 Gradle 1 Test 0 Tomcat 1 JavaWeb 7 Ajax 1 注解 3 css 2 报错 3 多数据源 1 Java基础 1 源码 2 Servlet 1 JSP 1 环境搭建 8 RabbitMQ 1 七牛云 1 Edit.md 1 图像识别 4 英语 2 Zookeeper 1

(转载)接近8000字的Spring/SpringBoot常用注解总结!安排!

  • 2020-05-18
  • 143
  • SpringBoot
非原创 > 原文作者:SnailClimb 本文转载自:https://www.imooc.com/article/304149 ## 前言 大家好,我是 Guide 哥!这是我的 221 篇优质原创文章。如需转载,请在文首注明地址,蟹蟹! 本文已经收录进我的 75K Star 的 Java 开源项目 JavaGuide:https://github.com/Snailclimb/JavaGuide 可以毫不夸张地说,这篇文章介绍的 Spring/SpringBoot 常用注解基本已经涵盖你工作中遇到的大部分常用的场景。对于每一个注解我都说了具体用法,掌握搞懂,使用 SpringBoot 来开发项目基本没啥大问题了! 整个目录如下,内容有点多: ![](http://img3.sycdn.imooc.com/5eaa987f0001279810802201.jpg) 为什么要写这篇文章? 最近看到网上有一篇关于 SpringBoot 常用注解的文章被转载的比较多,我看了文章内容之后属实觉得质量有点低,并且有点会误导没有太多实际使用经验的人(这些人又占据了大多数)。所以,自己索性花了大概 两天时间简单总结一下了。 因为我个人的能力和精力有限,如果有任何不对或者需要完善的地方,请帮忙指出!Guide 哥感激不尽! ## 1.`@ SpringBootApplication` 这里先单独拎出 `@ SpringBootApplication` 注解说一下,虽然我们一般不会主动去使用它。 Guide 哥:这个注解是 Spring Boot 项目的基石,创建 SpringBoot 项目之后会默认在主类加上。 ``` @SpringBootApplication public class SpringSecurityJwtGuideApplication { public static void main(java.lang.String[] args) { SpringApplication.run(SpringSecurityJwtGuideApplication.class, args); } } ``` 我们可以把 `@ SpringBootApplication`看作是 `@ Configuration`、`@ EnableAutoConfiguration`、`@ ComponentScan` 注解的集合。 ``` package org.springframework.boot.autoconfigure; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) public @interface SpringBootApplication { ...... } package org.springframework.boot; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Configuration public @interface SpringBootConfiguration { } ``` 根据 SpringBoot 官网,这三个注解的作用分别是: - `@ EnableAutoConfiguration`:启用 SpringBoot 的自动配置机制 - `@ ComponentScan`: 扫描被`@ Component` (`@ Service`,`@ Controller`)注解的 bean,注解默认会扫描该类所在的包下所有的类。 - `@ Configuration`:允许在 Spring 上下文中注册额外的 bean 或导入其他配置类 ## 2. Spring Bean 相关 ### 2.1. `@ Autowired` 自动导入对象到类中,被注入进的类同样要被 Spring 容器管理比如:Service 类注入到 Controller 类中。 ``` @Service public class UserService { ...... } @RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; ...... } ``` ### 2.2. `Component`,`@ Repository`,`@ Service`, `@ Controller` 我们一般使用 `@ Autowired` 注解让 Spring 容器帮我们自动装配 bean。要想把类标识成可用于 `@ Autowired` 注解自动装配的 bean 的类,可以采用以下注解实现: - `@ Component` :通用的注解,可标注任意类为 Spring 组件。如果一个 Bean 不知道属于哪个层,可以使用@Component 注解标注。 - `@ Repository` : 对应持久层即 Dao 层,主要用于数据库相关操作。 - `@ Service` : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。 - `@ Controller` : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面。 ### 2.3. `@ RestController` `@ RestController`注解是`@ Controller`和`@ ResponseBody`的合集,表示这是个控制器 bean,并且是将函数的返回值直 接填入 HTTP 响应体中,是 REST 风格的控制器。 Guide 哥:现在都是前后端分离,说实话我已经很久没有用过`@ Controller`。如果你的项目太老了的话,就当我没说。 单独使用 `@ Controller` 不加 `@ ResponseBody`的话一般使用在要返回一个视图的情况,这种情况属于比较传统的 Spring MVC 的应用,对应于前后端不分离的情况。`@ Controller` +`@ ResponseBody` 返回 JSON 或 XML 形式数据 关于`@ RestController` 和 `@ Controller`的对比,请看这篇文章: [@ RestController vs @ Controller](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247485544&idx=1&sn=3cc95b88979e28fe3bfe539eb421c6d8&chksm=cea247a3f9d5ceb5e324ff4b8697adc3e828ecf71a3468445e70221cce768d1e722085359907&token=1725092312&lang=zh_CN#rd "66") ### 2.4. `@ Scope` 声明 Spring Bean 的作用域,使用方法: ``` @Bean @Scope("singleton") public Person personSingleton() { return new Person(); } ``` 四种常见的 Spring Bean 的作用域: - singleton : 唯一 bean 实例,Spring 中的 bean 默认都是单例的。 prototype : 每次请求都会创建一个新的 bean 实例。 - request : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP request 内有效。 - session : 每一次 HTTP 请求都会产生一个新的 bean,该 bean 仅在当前 HTTP session 内有效。 ### 2.5. `Configuration` 一般用来声明配置类,可以使用 @Component注解替代,不过使用Configuration注解声明配置类更加语义化。 ``` @Configuration public class AppConfig { @Bean public TransferService transferService() { return new TransferServiceImpl(); } } ``` ## 3. 处理常见的 HTTP 请求类型 **5 种常见的请求类型: ** - GET :请求从服务器获取特定资源。举个例子:GET /users(获取所有学生) - POST :在服务器上创建一个新的资源。举个例子:POST /users(创建学生) - PUT :更新服务器上的资源(客户端提供更新后的整个资源)。举个例子:PUT /users/12(更新编号为 12 的学生) - DELETE :从服务器删除特定的资源。举个例子:DELETE /users/12(删除编号为 12 的学生) PATCH :更新服务器上的资源(客户端提供更改的属性,可以看做作是部分更新),使用的比较少,这里就不举例子了。 ### 3.1. GET 请求 @ GetMapping("users") 等价于@ RequestMapping(value="/users",method=RequestMethod.GET) ``` @GetMapping("/users") public ResponseEntity<List<User>> getAllUsers() { return userRepository.findAll(); } ``` ### 3.2. POST 请求 @ PostMapping("users") 等价于@ RequestMapping(value="/users",method=RequestMethod.POST) 关于`@ RequestBody`注解的使用,在下面的“前后端传值”这块会讲到。 ``` @PostMapping("/users") public ResponseEntity<User> createUser(@Valid @RequestBody UserCreateRequest userCreateRequest) { return userRespository.save(user); } ``` ### 3.3. PUT 请求 @ PutMapping("/users/{userId}") 等价于@ RequestMapping(value="/users/{userId}",method=RequestMethod.PUT) ``` @PutMapping("/users/{userId}") public ResponseEntity<User> updateUser(@PathVariable(value = "userId") Long userId, @Valid @RequestBody UserUpdateRequest userUpdateRequest) { ...... } ``` ### 3.4. DELETE 请求 @ DeleteMapping("/users/{userId}")等价于@ RequestMapping(value="/users/{userId}",method=RequestMethod.DELETE) ``` @DeleteMapping("/users/{userId}") public ResponseEntity deleteUser(@PathVariable(value = "userId") Long userId){ ...... } ``` ### 3.5. PATCH 请求 一般实际项目中,我们都是 PUT 不够用了之后才用 PATCH 请求去更新数据。 ``` @PatchMapping("/profile") public ResponseEntity updateStudent(@RequestBody StudentUpdateRequest studentUpdateRequest) { studentRepository.updateDetail(studentUpdateRequest); return ResponseEntity.ok().build(); } ``` ## 4. 前后端传值 **掌握前后端传值的正确姿势,是你开始 CRUD 的第一步! ** ### 4.1. `@ PathVariable` 和 `@ RequestParam` `@ PathVariable`用于获取路径参数,`@ RequestParam`用于获取查询参数。 举个简单的例子: ``` @GetMapping("/klasses/{klassId}/teachers") public List<Teacher> getKlassRelatedTeachers( @PathVariable("klassId") Long klassId, @RequestParam(value = "type", required = false) String type ) { ... } ``` 如果我们请求的 url 是:`/klasses/{123456}/teachers?type=web` 那么我们服务获取到的数据就是:`klassId=123456,type=web`。 ### 4.2. @RequestBody 用于读取 Request 请求(可能是 POST,PUT,DELETE,GET 请求)的 body 部分并且Content-Type 为 application/json 格式的数据,接收到数据之后会自动将数据绑定到 Java 对象上去。系统会使用HttpMessageConverter或者自定义的HttpMessageConverter将请求的 body 中的 json 字符串转换为 java 对象。 我用一个简单的例子来给演示一下基本使用! 我们有一个注册的接口: ``` @PostMapping("/sign-up") public ResponseEntity signUp(@RequestBody @Valid UserRegisterRequest userRegisterRequest) { userService.save(userRegisterRequest); return ResponseEntity.ok().build(); } ``` `UserRegisterRequest`对象: ``` @Data @AllArgsConstructor @NoArgsConstructor public class UserRegisterRequest { @NotBlank private String userName; @NotBlank private String password; @FullName @NotBlank private String fullName; } ``` 我们发送 post 请求到这个接口,并且 body 携带 JSON 数据: ``` {"userName":"coder","fullName":"shuangkou","password":"123456"} ``` 这样我们的后端就可以直接把 json 格式的数据映射到我们的 UserRegisterRequest 类上。 ![](http://img1.sycdn.imooc.com/5eaa988200014dbf10780338.jpg) 需要注意的是:一个请求方法只可以有一个`@ RequestBody`,但是可以有多个`@ RequestParam`和`@ PathVariable`。 如果你的方法必须要用两个 `@ RequestBody`来接受数据的话,大概率是你的数据库设计或者系统设计出问题了! ## 5. 读取配置信息 很多时候我们需要将一些常用的配置信息比如阿里云 oss、发送短信、微信认证的相关配置信息等等放到配置文件中。 下面我们来看一下 Spring 为我们提供了哪些方式帮助我们从配置文件中读取这些配置信息。 我们的数据源application.yml内容如下:: ``` wuhan2020: 2020年初武汉爆发了新型冠状病毒,疫情严重,但是,我相信一切都会过去!武汉加油!中国加油! my-profile: name: Guide哥 email: koushuangbwcx@163.com library: location: 湖北武汉加油中国加油 books: - name: 天才基本法 description: 二十二岁的林朝夕在父亲确诊阿尔茨海默病这天,得知自己暗恋多年的校园男神裴之即将出国深造的消息——对方考取的学校,恰是父亲当年为她放弃的那所。 - name: 时间的秩序 description: 为什么我们记得过去,而非未来?时间“流逝”意味着什么?是我们存在于时间之内,还是时间存在于我们之中?卡洛·罗韦利用诗意的文字,邀请我们思考这一亘古难题——时间的本质。 - name: 了不起的我 description: 如何养成一个新习惯?如何让心智变得更成熟?如何拥有高质量的关系? 如何走出人生的艰难时刻? ``` ### 5.1. @value(常用) 使用 `@ Value("${property}")` 读取比较简单的配置信息: ``` @Value("${wuhan2020}") String wuhan2020; ``` ### 5.2. @ ConfigurationProperties(常用) 通过`@ ConfigurationProperties`读取配置信息并与 bean 绑定。 ``` @Component @ConfigurationProperties(prefix = "library") class LibraryProperties { @NotEmpty private String location; private List<Book> books; @Setter @Getter @ToString static class Book { String name; String description; } 省略getter/setter ...... } ``` 你可以像使用普通的 Spring bean 一样,将其注入到类中使用。 ### 5.3. PropertySource(不常用) `@ PropertySource`读取指定 properties 文件 ``` @Component @PropertySource("classpath:website.properties") class WebSite { @Value("${url}") private String url; 省略getter/setter ...... } ``` 更多内容请查看我的这篇文章: [《10 分钟搞定 SpringBoot 如何优雅读取配置文件?》](https://mp.weixin.qq.com/s?__biz=Mzg2OTA0Njk0OA==&mid=2247486181&idx=2&sn=10db0ae64ef501f96a5b0dbc4bd78786&chksm=cea2452ef9d5cc384678e456427328600971180a77e40c13936b19369672ca3e342c26e92b50&token=816772476&lang=zh_CN#rd) ## 6. 参数校验 .... 待完善(后面的不常用)这里就不继续写了,可以看看原文。

Servlet3.0注解分析

  • 2020-04-22
  • 132
  • JavaWeb
在Servlet3.0出来之后,推出了几个常用的注解来帮助我们简化 web.xml 中的配置 今天我们就来总结一下这些注解的基本使用,以及和 web.xml 原来配置的对应关系。 ### 都有哪些注解 要想系统的了解都有哪些注解,最好的方法就是看源码呗。 我们知道,注解时使用在Servlet类上面的,那么我们就直接点进我们导入与Servlet相关的 jar 包里面看一看。 ![](/upload/annotation4.png) 找到 javax.servlet-api-4.0.1.jar 这个 jar 包,发现里面就有我们需要找的注解,下面我们来一一分析一下。 ### @ WebServlet - 这个注解用来标注一个 Servlet,该类需继承自 HttpServlet - 和我们在 web.xml 中配置的 <servlet> 功能一样 > Java代码 ``` @WebServlet(name = "test", urlPatterns = {"/user"}) public class UserServlet extends HttpServlet { // 逻辑代码 } ``` > web.xml配置 ``` <servlet> <servlet-name>test</servlet-name> <servlet-class>com.linkai.servlet.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>test</servlet-name> <url-pattern>/user</url-pattern> </servlet-mapping> ``` ### @ WebFilter - 用来配置过滤器的注解 ### @ WebListener - 用来配置监听器的注解 ### @ WebInitParam - 用来给Servlet传递参数的注解 在 @ WebServlet 中,我们看到这样一个方法 ``` WebInitParam [] initParams() default {}; ``` 显然@ WebInitParam应该是给Servlet初始化传递参数的,而且这个参数要放在@ WebServlet里面 未完,待续。。。666

SpringBoot项目中Ajax详解,结合@RequestBody和@ResponseBody

  • 2020-04-14
  • 153
  • SpringBoot
### 基本介绍 @ ResponseBody 和 @ RequestBody 经常在 Controller 层中使用,今天就结合Ajax来详解的介绍一下这两个注解。 #### @ RequestBody 用在参数前面 #####(1)前端Ajax传递的是JSON字符串 当前端发送的Ajax请求是传递的数据data是一个**JSON字符串**时,后端 Controller 层就可以使用 **@ ResponseBody** 注解结合 **Map** 来接收参数。 > 前端 ``` var inputTextObj = { "text": inputText }; $.ajax("/admin/tagGetSearchResult", { type: 'post', dataType: 'json', data: JSON.stringify(inputTextObj), //转换为字符串 contentType : "application/json", // 记得加上这个 }); ``` > 后端 ``` @RequestMapping("/tagGetSearchResult") @ResponseBody public String getSearchResult(@RequestBody HashMap<String, String> map) { String inputText = map.get("text"); // 获得Map里面的值(inputText) List<Tag> tags = tagService.queryLike(inputText); String str = JSON.toJSONString(tags); return str; } ``` #####(2)前端Ajax传递的是JSON对象 如果发送的Ajax的data是JSON对象,则后端可以直接使用 @ RequestParam 注解来接收参数,不需要使用 @ ResponseBody > 前端 ``` var dataObj = { "title": $('#article-title').val(), "blogid": tempBid, "my-editormd-markdown-doc": $("#my-editormd-markdown-doc").text(), "type": $('#my-type').val(), "original": original + '', "ifComment": ifComment + '', "tag": tagNames, // 标签名称 "published": '0', }; $.ajax("/admin/updateBlog", { type: "POST", data: dataObj, // 注意:这里传递的是一个 json 对象,后端需要利用 @RequestParam 注解 dataType: "text", // 返回的类型为纯文本字符串类型 traditional: true, }); ``` > 后端 ``` @RequestMapping("/updateBlog") @ResponseBody public String updateBlog(@RequestParam("blogid") String bid, @RequestParam("title") String title, @RequestParam("my-editormd-markdown-doc") String bcontent, @RequestParam("type") String typeName, @RequestParam("original") String orginal, @RequestParam("ifComment") String ifComment, @RequestParam("tag") String[] tags, @RequestParam("published") String published) { // 逻辑代码... } ``` #### @ ResponseBody 用在方法前面 表示直接返回一个字符串,处理Ajax请求时,如果后端查询出来的是一个 List 集合,那么可以转换为 JSON 字符串,结合 @ ResponseBody 返回。 - 具体可以看上面第(1)小点的后端代码 - 上面的 `JSON.toJSONString(tags);` 的 JSON 是使用的阿里巴巴的 FastJson,需要导入对应的依赖,如下: ``` <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.62</version> </dependency> ```