springboot框架基础知识

目录

1.pom文件详解

2.mysql对应java数据类型

3.yml文件

4.关于Profile配置

5.关于Spring Boot的配置文件

6.添加与Mybatis相关的配置

7.使用Mybatis访问数据

8.编写SQL语句时的代码提示

9.使用测试检验开发的数据访问功能

10.关于SLF4j日志

11.关于Service

12.关于抛出异常

13. 添加Web开发的依赖项

14.控制器

15.关于Knife4j框架

16.处理请求的方法的返回值

17.在Spring MVC框架中,向客户端响应JSON格式的数据

18.Spring MVC的统一处理异常机制 

19.响应结果中的null值

20.请求头的设计,RESTFUL风格

21.检查请求参数

22.处理跨域访问的错误

23.如何接受客户端参数,@RequestBody

24.Spring JDBC框架的事务管理

25.Spring框架


1.pom文件详解

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/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.6</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!-- Generated by https://start.springboot.io -->
    <!-- 优质的 spring/boot/data/security/cloud 框架中文文档尽在 => https://springdoc.cn -->

    <!--当前项目的信息-->
    <groupId>cn.tedu</groupId>
    <artifactId>csmall-product</artifactId>
    <!--版本可自由设定-->
    <version>0.0.1</version>

    <!--当前项目的属性配置-->
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <!--当前项目使用的依赖项-->
    <dependencies>
        <!--lombok依赖项用于实体类的相关操作,简化代码-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
            <!--scope标签是配置依赖项的作用域-->
            <scope>provided</scope>
        </dependency>

        <!--mybatis整合springboot依赖项-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!--mysql依赖项-->
        <!--当添加了数据库编程依赖项,无论是启用还是测试都会尝试链接数据库,读取配置信息,所以同时必须在配置文件中添加数据库配置信息-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!--springboot基础依赖项-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <!--springboot测试依赖项-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>



</project>

2.mysql对应java数据类型

tinyint / smallint / intInteger
bigintLong
varchar / char / text系列String
decimalBigDecimal
datetimeLocalDateTime

3.yml文件

YAML是一种编写配置文件的语法,表现为以.yml作为扩展名的文件。

相比.properties文件,其语法的改变有:

  • 原属性名中有小数点的部分,改为使用冒号+换行后空2格
  • 原属性名与属性值使用等于号分隔,改为使用冒号+1个空格
  • 如果多个配置中,属性名有相同的部分,则不必配置相同的部分,保持对应的空格(缩进)即可

4.关于Profile配置

  • application.properties是主配置文件,其中的所有配置都是默认加载的
  • application-自定义名称.properties作为文件名的全部是Profile配置,默认是不加载的,必须激活这些文件中的配置才会被加载
  • application.properties(主配置文件)中,使用spring.profiles.active属性,可以激活Profile配置,此属性的值就是Profile配置的文件名的自定义部分,如果有多个Profile配置需要激活,使用逗号分隔即可
  • 如果在application.properties(主配置文件)中,与在Profile配置中,存在完全相同的属性的配置,则以Profile配置为准

5.关于Spring Boot的配置文件

在Spring Boot项目中,在src/main/resources文件夹下存在application.properties文件,此文件是Spring Boot会自动读取的配置文件。

Spring Boot定义了许多特定用途的配置,在application.properties中,需要按照特定的属性名进行配置,则Spring Boot读取到了这些特定的配置后,会自动应用起来!

例如,添加连接数据库的配置:

spring.datasource.url=jdbc:mysql://localhost:3306/mall_pms?characterEncoding=utf-8&useUnicode=true&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root
spring.profiles.active=dev
mybatis.mapper-locations=classpath:mapper/*.xml

6.添加与Mybatis相关的配置

在每个项目中,当需要使用Mybatis实现数据库编程时,都需要添加2项一次性配置:配置Mapper接口所在的包(package)、配置XML文件在哪里。

关于配置Mapper接口所在的包,可以(以下做法二选一即可):

  • 【推荐】在配置类上使用@MapperScan注解,并指定注解的参数,此参数值就是包名
  • 在每个Mapper接口上添加@Mapper注解

则在项目的根包下创建config.MybatisConfiguration类,在此类上添加@Configuration注解,则可以将此类标记为“配置类”,然后,再添加@MapperScan注解来指定Mapper接口所在的包:

package cn.tedu.csmall.product.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("cn.tedu.csmall.product.mapper")
public class MybatisConfiguration {
}

另外,关于“配置XML文件在哪里”,需要通过配置文件(application.properties / application.yml / 相关Profile文件)中的mybatis.mapper-locations进行配置。由于此项配置的值,不会因为切换开发环境、测试环境等环境而变化,也不会因为使用不同的电脑来开发而变化,所以,应该将其配置在主配置文件中!

先在src/main/resources下创建mapper文件夹,此文件夹将用于存放配置SQL语句的XML文件。

application.yml中添加配置:

mybatis:
  mapper-locations: classpath:mapper/*.xml

 classpath是指main包下的两个文件夹,只是放的文件意义不一样,编译打包都是在一个文件夹下

7.使用Mybatis访问数据

首先,需要创建接口,通常每张数据表都有一个对应的Mapper接口,并在接口中声明抽象方法

抽象方法的声明:

返回值类型:如果要执行的数据访问操作是增、删、改类型的,始终使用int作为返回值类型,表示“受影响的行数”,如果要执行数据访问操作是查询类型的,只需要保证返回值类型能够“放得下”查询结果即可

方法名称:自定义,建议不要重载,《阿里巴巴Java开发手册》提供的参考

1) 获取单个对象的方法用 get 做前缀。
2) 获取多个对象的方法用 list 做前缀。
3) 获取统计值的方法用 count 做前缀。
4) 插入的方法用 save/insert 做前缀。
5) 删除的方法用 remove/delete 做前缀。
6) 修改的方法用 update 做前缀。

然后,需要准备好XML文件,在XML文件中配置抽象方法映射的SQL语句。

XML文件的内部详解:

  • 根标签必须是<mapper>,且此标签必须配置namespace属性,取值为对应的接口的全限定名(包名加类名)

  • 在根标签的子级,可以使用<insert> / <delete> / <update> / <select>这些标签来配置增、删、改、查对应的SQL语句,这些标签都必须配置id属性,取值为对应的抽象方法的名称

    • 其实,<update><delete>这2个标签可以随意调换使用,例如,配置DELETE语句可以使用<update>标签,甚至,在不考虑获取自动编号的ID时,<insert>标签和<update><delete>也可以随意调用使用,因为这3种数据访问操作在JDBC的底层实现是一样的,当然,这种乱用的方式肯定是非常不建议的
  • <insert>这4种标签的子级,编写SQL语句,参数部分使用#{名称}格式的占位符来表示,其中,占位符中的“名称”应该是参数名称,或封装类型中的属性名

  • 严格说来,在#{}格式的占位符中的名称,将被用于生成Setter & Getter的名称,然后,Mybatis框架会自动调用实体类的get和set方法,#{}里面的是属性,会被拼上get+属性名,属性名首字母大写

  • 如果配置的是<insert>标签,并且,插入数据的表的主键是自动编号的,应该在此标签上配置useGeneratedKeys="true"keyProperty="主键属性"这2个属性,以获取自动编号的ID值,创建的实体的参数id插入前和插入后是不一样的,插入前是null,插入后是自动编号的id,本质是通过set方法,设置值

  • 如果涉及批量操作,需要通过<foreach>标签来遍历参数对象,关于此标签的使用:

    • collection属性:表示被遍历的对象,当抽象方法的参数只有1个,且没有添加@Param注解时,如果参数是数组或可变参数,则此属性的值为array,如果参数是List集合,则此属性的值为list;当抽象方法的参数超过1个,需要添加@Param注解,则此属性的值为注解的配置值
    • item属性:表示遍历过程中各元素的名称,是自定义名称,并且,在<foreach>子级的#{}占位符中,也使用此名称表示被遍历到的元素
    • separator属性:表示遍历过程中各值之间的分隔符号
    • <foreach>标签是Mybatis的“动态SQL”标签之一
  • 关于动态SQL的<if>标签,可以对参数进行判断,从而确定SQL语句中应该包含或不包含哪些片段

    • 需要注意,没有所谓的else标签,如果一定要实现类似Java中if...else...的效果,可以使用2个条件完全相反的<if>标签(虽然执行效率会差一些),或者,使用<choose>系列标签,语法格式如下:

      <choose>
      	<when test="条件">
          	满足条件时的SQL片段
          </when>
          <otherwise>
          	不满足条件时的SQL片段
          </otherwise>
      </choose>
      
  • 如果涉及修改数据的操作,当使用了<if>实现动态SQL时,通常,应该使用<set>标签将更新列表框住,并且,SQL语句中不需要写SET关键字

  • 如果配置的是<select>标签,此标签必须配置resultTyperesultMap这2个属性中的某1个

    • resultType的值是基本数据类型时,直接使用类型名称作为此属性值即可,例如resultType="int"
    • resultType的值是引用数据类型时,需要使用类型的全限定名作为此属性值,例如resultType="cn.tedu.xxx.User",但是,如果类型是java.lang包下的,则可以不写包名,例如resultType="Integer"
  • 在编写查询的SQL语句时,可以使用<sql>标签封装查询的字段列表,并使用<include>标签来引用封装的查询字段列表

    • 由于IntelliJ IDEA会检查每个标签的子级内容的语法,所以,在<sql>标签下直接写字段列表,IntelliJ IDEA会提示错误,但是并不影响运行,可以使用<if test="true">将字段列表框住,以“欺骗”IntelliJ IDEA使之不报错
    • 通常,在<include>标签的子级并不编写任何代码,所以,此标签推荐使用单标签格式
  • 建议为所有的“非统计查询”配置<resultMap>

8.编写SQL语句时的代码提示

在设置中,指定SQL Dialects配置,如果完成配置后,在XML文件中编写SQL语句仍没有提示,可以尝试删除并重新配置Database面板,或将方言在MariaDB和MySQL之间切换。

9.使用测试检验开发的数据访问功能

在Spring Boot项目中,所有的测试类都应该创建在src/test/java下的根包

当需要执行的测试是基于加载整个项目环境的(例如需要读取配置文件、需要使用@Autowired自动装配等),测试类必须添加@SpringBootTest注解。方法上添加@test

如果@Autowired自动装配爆红,可能是idea软件的问题,也有可能是mapper接口上没有添加@Repository注解,也可以不处理,不推荐使用required = false

10.关于SLF4j日志

在开发实践中,通常是禁止使用System.out.println()这种语句输出信息的

在Spring Boot项目中,基础依赖项(spring-boot-starter)中已经包含了日志相关的依赖项,可以直接使用日志框架来输出信息!

在添加了Lombok后,在任何类的声明之前,添加@Slf4j注解,则编译期会自动声明一个名为log的变量,所以,可以在类中通过此变量来输出日志。

如果没有使用Lombok,可以自行声明日志变量,例如:

private static Logger logger = LoggerFactory.getLogger(Slf4jTests.class); 

在日志框架中,根据日志信息的重要程度,划分了几个等级

  • trace:跟踪信息
  • debug:调试信息
  • info:一般信息
  • warn:警告信息
  • error:错误信息

 在没有加载Spring Boot的情况下,日志的默认显示级别是debug,只会显示此级别及更加重要的级别的日志,如果加载了Spring Boot(例如在测试类上添加了@SpringBootTest注解),日志的默认显示级别是info

可以在配置文件(application.properties / application.yml / 相关Profile配置)中配置logging.level.包名属性,以指定某个包下的所有类的默认日志显示级别,此属性的值为5个级别中的某1个

配置包名时,不必把包名配置得特别具体,可以作用于其子孙包下所有的类,但是,必须至少配置1级包名,例如配置到cn这一级包,不可以完全不配置包名

log.info("x = {}, y = {}, x + y = {}", x , y , x + y); // 使用日志输出变量的做法

SLF4j其实是一种日志框架的标准,并没有具体实现日志的输出功能,通常,是使用log4jlogback这些日志框架来实现具体功能的!

11.关于Service

在《阿里巴巴Java手册》中的强制规约:

强制】对于 Service 和 DAO 类,基于 SOA 的理念,暴露出来的服务一定是接口,内部
的实现类用 Impl 的后缀与接口区别。
正例:CacheServiceImpl 实现 CacheService 接口

12.关于抛出异常

当使用抛出异常的方式表示“操作失败”时,不可以使用任何已有的异常(JDK中原生的异常类型,及添加的依赖项中包含的异常类型),必须自定义异常,则后续捕获并处理时,一定符合抛出异常时的情景。

定义异常必须继承自某个已存在的异常类型,强烈建议继承自RuntimeException,其原因有:

  • 原因1:在项目中将使用全局异常处理器统一处理异常,要想统一处理,则Service组件、Controller组件都必须抛出异常,才能由Spring MVC框架捕获到异常,进而通过全局异常处理器进行统一的处理!RuntimeException不会受到异常的相关语句约束,而非RuntimeException一旦被抛出,方法的声明、方法的调用者的声明等都需要声明抛出此异常,由于抛出异常是固定的做法,没有必要在各个方法上都声明抛出此异常,所以,应该使用RuntimeException
  • 原因2:配合Spring JDBC框架实现事务管理!

13. 添加Web开发的依赖项

在现有的项目中,只需要将spring-boot-starter改为spring-boot-starter-web,此依赖项中包含了spring-boot-starter这个基础依赖项

当添加了以上依赖项,你的项目会有以下明显的变化:

  • 启用项目时,会自动启用Tomcat(你的项目也会部署到这个Tomcat上),默认占用8080端口
  • src/main/resources下的static文件夹会是默认的静态资源文件夹,在此文件夹下的资源(例如网页、图片等)可以直接通过HTTP协议的URL直接访问
    • 如果创建项目时勾选了Web依赖项,会自动创建此文件夹,如果创建项目时未勾选Web依赖项,而是手动添加spring-boot-starter-web,不会自动创建此文件夹,但可以手动创建,是等效的

在配置文件中,可以通过server.port属性指定Tomcat占用的端口号,默认8080,端口号的最大值是65535

14.控制器

在类上添加@RestController注解,在类中自动装配Service的对象,并且,自定义方法处理请求

 调用顺序controller>service>mapper

 开发顺序mapper>service>controller

在方法上添加@RequestMapping,在Spring MVC框架中,@RequestMapping注解的主要作用是配置“请求路径”与“处理请求的方法”的映射关系

@RequestMapping的源代码中,可以看到它的声明

在配置路径时,Spring MVC会自动处理必要的/(如果缺少,则添加,如果多余,则去除)

Spring MVC框架还提供了基于@RequestMapping的衍生注解,@GetMapping、@PostMapping等

15.关于Knife4j框架

Knife4j是一款在线API文档框架,可以基于当前项目的控制器类中的配置生成文档,并自带调试功能

  • 添加依赖
    • **注意:**本次使用的Knife4j的版本,要求项目中的Spring Boot版本必须是2.6以下版本(不包含2.6)
  • 在主配置文件(application.properties / application.yml)中开启增强模式
    • 配置knife4j.enable属性,取值为true
  • 添加配置类
    • 是相对固定的代码,复制粘贴即可
    • **注意:**需要检查配置类中所配置的包名,必须是当前项目中控制器类所在的包

 <dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>2.0.9</version>
</dependency>

完成后,启用项目,通过 doc.html 即可访问在线API文档,即:http://localhost:8080/doc.html 

前提是在类、方法、POJO类型的属性、请求参数上添加注解,才会有效果

16.处理请求的方法的返回值

在前后端分离的做法中,服务器端是不处理视图的,而是将处理请求后得到的数据响应到客户端,由客户端决定如何处理此数据

使用@ResponseBody注解,方法的返回值会直接响应到客户端去!

@ResponseBody注解添加在控制器类上,则当前控制器类中所有处理请求的方法都是响应正文

而@Controller注解的类会被作为控制器类,两个注解也可以改为使用@RestController

17.在Spring MVC框架中,向客户端响应JSON格式的数据

处理请求的方法必须是响应正文

开启注解驱动

  • 如果是使用XML配置的Spring MVC项目,需要在XML配置文件中添加<annotation-driven/>
  • 如果是使用注解配置的Spring MVC项目,需要在配置类上添加@EnableWebMvc
  • 如果是Spring Boot项目,不需要添加任何配置

添加jackson-databind依赖项

  • spring-boot-starter-web依赖项中包含此依赖项

使用自定义的数据类型作为处理请求的方法的返回值类型

18.Spring MVC的统一处理异常机制 

类上添加@RestControllerAdvice注解,将可以作用于整个项目中任何处理请求的过程中,方法上添加@ExceptionHandler

在Spring MVC框架中,处理请求的方法都是被框架所调用的,所以,处理请求的方法抛出的异常也都会被框架捕获到,则框架会自动的使用此异常对象来调用处理异常的方法!

这样就不用try..catch...捕获异常了。

19.响应结果中的null值

null值的属性响应到客户端去是没有任何意义的

属性上配置@JsonInclude注解,也可以将此注解添加在类上,则类中每个属性都是此配置,还可以在配置文件中通过spring.jackson.default-property-inclusion属性进行作用于整个项目的全局配置

20.请求头的设计,RESTFUL风格

类上添加@RequestMapping("/xxx"),方法上@PostMapping("/{id}/delete"),方法的参数上添加@PathVariable

@PostMapping("/{id}/delete")
public ??? delete(@PathVariable Long id) {
    // 暂不关心方法的实现
}

@PostMapping("/{id}/delete")
public ??? delete(@PathVariable("id") Long albumId) {
    // 暂不关心方法的实现
}

 可以在占位符名称的右侧、在右大括号的左侧添加1个冒号,并在冒号的右侧可以添加正则表达式,以限制参数值的基本格式@PostMapping("/{id:[0-9]+}/delete")

客户端提交的请求路径中,占位符位置的内容无法被转换成Long类型时,将出现400错误

占位符位置的内容不匹配以上正则表达式时,将出现404错误。

21.检查请求参数

Spring Validation框架是用于检查请求参数的基本格式的框架

1.添加spring-boot-starter-validation依赖项

2.在处理请求的方法的被检查参数上添加@Valid@Validated注解,表示需要对此参数进行检查

3.在POJO类的属性上添加注解,例如@NotNull注解,@NotNull上可以配置message属性,用于配置“检查不通过时的提示文本”

如果检查不通过,会出现BindException,包含全部错误信息。可以在全局异常处理器中配置,提示全部文本,或者提示某一个,可以在配置类添加快速失败机制,检查到一个错误马上返回

对于检查未封装的请求参数,与上面不同

类上添加@Validated注解,检查的参数上添加检查注解

@PostMapping("/{id:[0-9]+}/delete")
public String delete(@Range(min = 1, max = 10000) @PathVariable Long id) {
    // 暂不关心方法的具体实现
}

这种检查抛出的异常类型是ConstraintViolationException,也可以在全局异常处理中配置

使用Validation框架检查数据的基本格式时,常用的检查注解有:

  • @NotNull:不允许为null值,即客户端必须提交此参数,可用于任何类型的参数
  • @NotEmpty:不允许为空字符串,即不允许是长度为0的字符串,仅用于字符串类型的参数
  • @NotBlank:不允许为空白的字符串,即不允许仅由空格、TAB制表位、换行等空白组成的字符串,仅用于字符串类型的参数
  • @Length:限制字符串的长度,也可以用于检查集合等数据的长度,但不常见,通常仅用于字符串类型的参数
  • @Pattern:通过正则表达式检查字符串的格式,此注解的regexp属性是定义正则表达式的属性
    • 仅用于字符串类型的参数
  • @Min:限制最小值,仅用于整型数值类型的参数
  • @Max:限制最大值
  • @Range:限制取值区间,默认最小值为0,最大值是long类型的上限值,仅用于整型数值类型的参数

检查请求参数的原则,服务器端对客户端提交的请求参数的值应该保持“不信任”的态度,而且客户端仍有必要对即将提交的请求参数进行检查

22.处理跨域访问的错误

当客户端向服务器端提交跨域(提交请求的、被请求的,不在同一台服务器,或不是同一个服务器同一端口)**的异步请求时,默认情况下,服务器端都是不支持的,所以,在客户端的浏览器的控制台会提示错误

要解决这个问题,服务器端必须允许跨域访问!

在基于Spring MVC的项目中,需要自定义配置类,实现WebMvcConfigurer接口,重写其中的addCorsMappings()方法,在其中配置允许跨域的访问。

@Slf4j
@Configuration
public class WebMvcConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOriginPatterns("*")
                .allowedHeaders("*")
                .allowedMethods("*")
                .allowCredentials(true)
                .maxAge(3600);
    }

}

23.如何接受客户端参数,@RequestBody

当客户端提交请求时,使用整个对象(this.ruleForm)作为请求参数,如果服务器端处理请求的方法的参数之前没有使用@RequestBody,将接收不到客户端提交的请求参数,即:对于服务器端而言,各请求参数均是null值!

当请求参数上添加了@RequestBody后,在Knife4j的API文档中,调试界面将不再提供各请求参数的输入框,而是需要自行组织JSON格式的请求参数进行调试!

当服务器端没有在请求参数之前添加@RequestBody时,客户端提交的请求参数必须是FormData格式的,例如:

let fromData = 'name=' + this.ruleForm.name
              + '&description=' + this.ruleForm.description
              + '&sort=' + this.ruleForm.sort;

 总结:要么在参数前添加注解,要么把请求参数转化为FromData格式

24.Spring JDBC框架的事务管理

事务(Transaction):是数据库(例如MySQL等)中的能够保障若干个写操作(增、删、改)要么全部成功,要么全部失败的机制

使用@Transcational注解,即可使得对应的方法是“事务性”的。


25.Spring框架

Spring框架主要解决了创建对象、管理对象的相关问题。

所有由Spring框架创建的对象,会被Spring框架保存在ApplicationContext(应用程序上下文)中,后续,当需要这些对象时,Spring会自动从ApplicationContext中取出并使用。

由于Spring的ApplicationContext中会保存若干个对象,所以通常也称之为“Spring容器”。

Spring框架的核心包括:

  • IoC = Inversion of Controller,即控制反转
  • AOP 面向切面编程

在Spring Boot项目中,启动类上添加了@SpringBootApplication注解,此注解使用了@ComponentScan作为其元注解。

使用@ComponentScan注解,即可实现:当加载此配置类时,Spring框架会执行组件扫描,扫描特定的包及其子级包下是否存在组件类,如果找到组件类,则Spring框架会自动创建此组件类的对象。

如果使用@ComponentScan时,没有配置注解参数,扫描的根包就是当前配置类所在的包;使用@ComponentScan注解时,还可以配置此注解的basePackages / value属性来指定需要扫描的若干个包。

如果被扫描的类添加了组件相关注解,此类就会被视为“组件类”,在Spring框架中,组件注解有:

  • @Component:通用注解
  • @Controller:添加在控制器类上
  • @Service:添加在业务实现类上
  • @Repository:添加在存取数据的类(例如对数据库做增删改查的类)上

在Spring中,还有一个非常特殊的组件注解:

  • @Configuration

在Spring MVC中,还新定义了注解用于标识组件类,这些新的注解都是基于@Component注解:

  • @RestController
  • @ControllerAdvice
  • @RestControllerAdvice

在配置类中,可以自定义方法,返回特定类型的对象,并在此方法上添加@Bean注解,则Spring框架加载此配置类时,会自动调用这些方法,从而得到方法返回的对象。

关于用法的选取

如果需要Spring创建的是自定义类的对象,推荐优先选取“组件扫描”的做法。

如果需要Spring创建的不是自定义类的对象,则无法选取“组件扫描”的做法,因为你无法在别人写的类上添加组件注解,只能使用“@Bean方法”的做法。

关于Spring Bean的名称

由Spring框架创建的对象均可称之为Spring Bean。每个Spring Bean都有名称。

如果使用组件扫描创建的对象,Spring Bean的名称:默认情况下,当类名的第1个字母是大写的,且第2个字母是小写的,则Spring Bean的名称就是将类名的首字母改为小写,例如CategoryServiceImpl类的Spring Bean名称就是categoryServiceImpl,如果不满足以上条件,则Spring Bean名称就是类名。如果需要自定义为其它名称,可以配置组件注解的参数,例如@Service("categoryService")

如果使用@Bean方法创建的对象,Spring Bean的名称默认是方法名称,也可以配置@Bean注解的参数,例如@Bean("categoryService")

Spring框架创建的对象的作用域

由Spring框架创建的对象,默认是“单例”的。

但Spring框架并不是使用了单例模式,只是它管理的对象具有与单例模式的特点。

可以通过@Scope注解修改Spring管理的对象的作用域,在此注解中配置参数值为"prototype"时,对象将不再是单例的,与普通的局部变量的作用域相同,当此注解的参数值是"singleton"时,对象是单例的,由于单例是默认的状态,所以,通常不会使用到此值。

如果是通过组件扫描的方法来创建对象,则在类的声明上使用@Scope注解

如果是通过@Bean方法来创建对象,则在方法的声明上使用@Scope注解

由Spring框架创建的对象,如果是“单例”的,默认是“饿汉式”的。

如果希望被创建的单例对象是“懒汉式”的,可以通过@Lazy注解进行配置。与@Scope注解的使用方式相同,如果是通过组件扫描创建的对象,可以在类上添加此注解,如果是通过@Bean方法创建的对象,可以在方法上添加此注解。

26.自动装配

Spring的自动装配机制表现为:当特定的量(类的属性,或被Spring自动调用的方法的参数)需要值时,使用待定的做法,可以使得Spring使用容器中的对象为这些量自动赋值。

最常见的用法是在类的属性上使用@Autowired注解

关于@Autowired@Resource的区别:

  • @Resource是Java注解(是javax.annotation包中的),@Autowired是Spring框架的注解
  • @Resource注解是优先按照名称进行匹配,再检查类型是否相同,@Autowired是先根据类型查找匹配的对象,如果超过1个,再尝试根据名称进行匹配
  • 提示:如果有且仅有1个类型匹配的Spring Bean,这2个注解都可以成功装配,如果匹配类型的Spring Bean超过1个,只要其中1个能匹配名称,这2个注解都可以成功装配,如果都不匹配名称,这2个注解都无法成功装配

Spring在处理自动装配时,有多种装配机制:

  • 属性注入

  • Setter注入

  • 构造方法注入

通过构造方法注入时:

  • 如果类中仅有1个构造方法,不必添加@Autowired注解
  • 如果类中有多个构造方法,默认情况下,Spring会自动尝试调用无参数构造方法(如果存在的话)
  • 如果类中有多个构造方法,希望Spring调用特定的某个构造方法,需要在此构造方法上添加@Autowired注解

在使用@Autowired时,如果存在多个匹配类型的Spring Bean,还可以使用@Qualifier注解来指定装配的Spring Bean的名称

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂铁不狂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值