SpringBoot(1)---常用注解

【一】SpringBoot介绍

(1)先从Spring谈起

我们知道Spring是重量级企业开发框架 Enterprise JavaBean(EJB) 的替代品,Spring为企业级Java开发提供了一种相对简单的方法,通过 DI依赖注入AOP面向切面编程 ,用简单的 Java对象(Plain Old Java Object,POJO) 实现了EJB的功能

虽然Spring的组件代码是轻量级的,但它的配置却是重量级的(需要大量XML配置) 。Spring 2.5引入了基于注解的组件扫描,这消除了大量针对应用程序自身组件的显式XML配置。Spring 3.0引入了基于Java的配置,这是一种类型安全的可重构配置方式,可以代替XML。

尽管如此,我们依旧没能逃脱配置的魔爪。开启某些Spring特性时,比如事务管理和Spring MVC,还是需要用XML或Java进行显式配置。启用第三方库时也需要显式配置,比如基于Thymeleaf的Web视图。配置Servlet和过滤器(比如Spring的DispatcherServlet)同样需要在web.xml或Servlet初始化代码里进行显式配置。组件扫描减少了配置量,Java配置让它看上去简洁不少,但Spring还是需要不少配置。

光配置这些XML文件都够我们头疼的了,占用了我们大部分时间和精力。除此之外,相关库的依赖非常让人头疼,不同库之间的版本冲突也非常常见。

不过,好消息是:Spring Boot让这一切成为了过去。

(2)再来谈谈 Spring Boot

官方的介绍:

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”…Most Spring Boot applications need very little Spring configuration.(Spring Boot可以轻松创建独立的生产级基于Spring的应用程序,只要通过 “just run”(可能是run ‘Application’或java -jar 或 tomcat 或 maven插件run 或 shell脚本)便可以运行项目。大部分Spring Boot项目只需要少量的配置即可)

简而言之,从本质上来说,Spring Boot就是Spring,它做了那些没有它你自己也会去做的Spring Bean配置。

为什么需要 Spring Boot?

Spring Framework旨在简化J2EE企业应用程序开发。Spring Boot Framework旨在简化Spring开发。

Spring Boot的主要优点
  1. 开发基于 Spring 的应用程序很容易。
  2. Spring Boot 项目所需的开发或工程时间明显减少,通常会提高整体生产力。
  3. Spring Boot不需要编写大量样板代码、XML配置和注释。
  4. Spring引导应用程序可以很容易地与Spring生态系统集成,如Spring JDBC、Spring ORM、Spring Data、Spring Security等。
  5. Spring Boot遵循“固执己见的默认配置”,以减少开发工作(默认配置可以修改)。
  6. Spring Boot 应用程序提供嵌入式HTTP服务器,如Tomcat和Jetty,可以轻松地开发和测试web应用程序。(这点很赞!普通运行Java程序的方式就能运行基于Spring Boot web 项目,省事很多)
  7. Spring Boot提供命令行接口(CLI)工具,用于开发和测试Spring Boot应用程序,如Java或Groovy。
  8. Spring Boot提供了多种插件,可以使用内置工具(如Maven和Gradle)开发和测试Spring Boot应用程序。

【二】常用注解

代码示例

@RestController
@RequestMapping("/api")
public class BookController {

    private List<Book> books = new ArrayList<>();

    @PostMapping("/book")
    public ResponseEntity<List<Book>> addBook(@RequestBody Book book) {
        books.add(book);
        return ResponseEntity.ok(books);
    }

    @DeleteMapping("/book/{id}")
    public ResponseEntity deleteBookById(@PathVariable("id") int id) {
        books.remove(id);
        return ResponseEntity.ok(books);
    }

    @GetMapping("/book")
    public ResponseEntity getBookByName(@RequestParam("name") String name) {
        List<Book> results = books.stream().filter(book -> book.getName().equals(name)).collect(Collectors.toList());
        return ResponseEntity.ok(results);
    }
}

(1)@SpringBootApplication

看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。根据 SpringBoot官网,这三个注解的作用分别是:

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @ComponentScan: 扫描被@Component (@Service,@Controller)注解的bean,注解默认会扫描该类所在的包下所有的类
  • @Configuration:允许在上下文中注册额外的bean或导入其他配置类

(2)@RestController

将返回的对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中。绝大部分情况下都是直接以 JSON 形式返回给客户端,很少的情况下才会以 XML 形式返回。转换成 XML 形式还需要额为的工作,直接将对象数据直接以 JSON 形式写入 HTTP 响应(Response)中。关于@Controller和@RestController 的对比,(@Controller +@ResponseBody= @RestController)。
在这里插入图片描述

(3)@RequestMapping

上面的示例中没有指定 GET 与 PUT、POST 等,因为**@RequestMapping默认映射所有HTTP Action**,你可以使用@RequestMapping(method=ActionType)来缩小这个映射。例如@RequestMapping(method=GET)

(4)@PostMapping

实际上就等价于 @RequestMapping(method = RequestMethod.POST),同样的 @DeleteMapping ,@GetMapping也都一样,常用的 HTTP Action 都有一个这种形式的注解所对应。

(5)@PathVariable

可以将 HttpRequest body 中的 JSON 类型数据反序列化为合适的 Java 类型

(6)@RequestBody

可以将 HttpRequest body 中的 JSON 类型数据反序列化为合适的 Java 类型。

(7)ResponseEntity

表示整个HTTP Response:状态码,标头和正文内容。我们可以使用它来自定义HTTP Response 的内容。

(8)@RestController vs @Controller

(8.1)Controller 返回一个页面(前后端不分离,返回的string是视图的名称)

单独使用 @Controller 不加 @ResponseBody的话一般使用在要返回一个视图的情况,这种情况属于比较传统的Spring MVC 的应用,对应于前后端不分离的情况。
在这里插入图片描述
当我们需要直接在后端返回一个页面的时候,Spring 推荐使用 Thymeleaf 模板引擎。Spring MVC中@Controller中的方法可以直接返回模板名称,接下来 Thymeleaf 模板引擎会自动进行渲染,模板中的表达式支持Spring表达式语言(Spring EL)。如果需要用到 Thymeleaf 模板引擎,注意添加依赖!不然会报错。

@Controller
public class HelloController {
    @GetMapping("/hello")
    public String greeting(@RequestParam(name = "name", required = false, defaultValue = "World") String name, Model model) {
        model.addAttribute("name", name);
        return "hello";
    }
}

Spring 会去 resources 目录下 templates 目录下找,所以建议把页面放在 resources/templates 目录下

(8.2)@RestController 返回JSON 或 XML 形式数据

但@RestController只返回对象,对象数据直接以 JSON 或 XML 形式写入 HTTP 响应(Response)中,这种情况属于 RESTful Web服务,这也是目前日常开发所接触的最常用的情况(前后端分离)。
在这里插入图片描述
如果你需要在Spring4之前开发 RESTful Web服务的话,你需要使用@Controller 并结合@ResponseBody注解,也就是说@Controller +@ResponseBody= @RestController(Spring 4 之后新加的注解)。

@ResponseBody 注解的作用是将 Controller 的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到HTTP 响应(Response)对象的 body 中,通常用来返回 JSON 或者 XML 数据,返回 JSON 数据的情况比较多。

SpringBoot 默认集成了 jackson ,对于此需求你不需要添加任何相关依赖。

@Controller
public class HelloController {
    @PostMapping("/hello")
    @ResponseBody
    public Person greeting(@RequestBody Person person) {
        return person;
    }

}

使用 post 请求访问 http://localhost:8080/hello ,body 中附带以下参数,后端会以json 格式将 person 对象返回。

{
“name”: “teamc”,
“age”: 1
}

(9)@PostConstruct与@PreDestroy

@PostConstruct和@PreDestroy 是两个作用于 Servlet 生命周期的注解,被这两个注解修饰的方法可以保证在整个 Servlet 生命周期只被执行一次,即使 Web 容器在其内部中多次实例化该方法所在的 bean。

这两个注解分别有什么作用呢?
  • @PostConstruct : 用来修饰方法,标记在项目启动的时候执行这个方法,一般用来执行某些初始化操作比如全局配置。PostConstruct 注解的方法会在构造函数之后执行,Servlet 的init()方法之前执行。
  • @PreDestroy : 当 bean 被 Web 容器的时候被调用,一般用来释放 bean 所持有的资源。。@PreDestroy 注解的方法会在Servlet 的destroy()方法之前执行。
被这个注解修饰的方法需要满足下面这些基本条件:
  • 非静态
  • 该方法必须没有任何参数,除非在拦截器的情况下,在这种情况下,它接受一个由拦截器规范定义的InvocationContext对象
  • void()也就是没有返回值
  • 该方法抛出未检查的异常

我们新建一个 Spring 程序,其中有一段代码是这样的,输出结果会是什么呢?

@Configuration
public class MyConfiguration {
    public MyConfiguration() {
        System.out.println("构造方法被调用");
    }

    @PostConstruct
    private void init() {
        System.out.println("PostConstruct注解方法被调用");
    }

    @PreDestroy
    private void shutdown() {
        System.out.println("PreDestroy注解方法被调用");
    }
}
替换方案

但是 J2EE已在Java 9中弃用 @PostConstruct和@PreDestroy这两个注解 ,并计划在Java 11中将其删除。我们有什么更好的替代方法吗?当然有!

@Configuration
public class MyConfiguration2 implements InitializingBean, DisposableBean {
    public MyConfiguration2() {
        System.out.println("构造方法被调用");
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("afterPropertiesSet方法被调用");
    }

    @Override
    public void destroy() {
        System.out.println("destroy方法被调用");
    }

}

输出结果如下,可以看出实现Spring 提供的 InitializingBean和 DisposableBean接口的效果和使用**@PostConstruct和@PreDestroy** 注解的效果一样。

但是,Spring 官方不推荐使用上面这种方式,如果你还是非要使用 Java 9 及以后的版本使用 @PostConstruct和@PreDestroy 这两个注解的话,你也可以手动添加相关依赖。
Maven:

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

Gradle:

compile group: ‘javax.annotation’, name: ‘javax.annotation-api’, version: ‘1.3.2’

【三】其他注解

【1】@ConfigurationProperties

在 SpringBoot 中,当想需要获取到配置文件数据时,除了可以用 Spring 自带的 @Value 注解外,SpringBoot 还提供了一种更加方便的方式:@ConfigurationProperties。只要在 Bean 上添加上了这个注解,指定好配置文件的前缀,那么对应的配置文件数据就会自动填充到 Bean 中。

比如在application.properties文件中有如下配置文件

config.username=jay.zhou
config.password=3333

那么按照如下注解配置,SpringBoot项目中使用@ConfigurationProperties的Bean,它的username与password就会被自动注入值了。就像下面展示的那样

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
 
@Component
@ConfigurationProperties(prefix = "config")
public class TestBean{
 
    private String username;
    
    private String password;
}

【2】@Data

@Data注解的主要作用是提高代码的简洁,使用这个注解可以省去实体类中大量的get()、 set()、 toString()等方法。

属于lombok插件的注解。其他的一些注解有:

  • @Data : 注在类上,提供类的get、set、equals、hashCode、toString等方法
  • @AllArgsConstructor :注在类上,提供类的全参构造 @NoArgsConstructor :注在类上,提供类的无参构造
  • @Setter :注在属性上,提供 set 方法
  • @Getter :注在属性上,提供 get 方法
  • @EqualsAndHashCode
    :注在类上,提供对应的 equals 和 hashCode 方法
  • @Log4j/@Slf4j :注在类上,提供对应的 Logger
    对象,变量名为 log

【3】@TableField

(1)@TableField(value = “email”)//指定数据库表中字段名

如果数据库和实体类的字段名不一致,可以使用@TableField注解指定数据库表中字段名。
在这里插入图片描述
(2)@TableField(exist = “false”)//数据库表中不存在的数据,在实体类中指定。

如果数据库表中不存在字段,在实体类中使用@TableField注解指定。

例如:数据库表中没有address字段,可以在该字段上方使用@TableField(exist = “false”)来指定。

(3)@TableField(select = “false”)//查询时不返回该字段的值

如果不想被查询出来该字段,可以使用@TableField注解来隐藏该字段的查询结果。

例如:不想被查出来password字段的值,就可以使用@TableField注解。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值