码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 项目中使用到的Spring注解及其作用


    目录

    启动类相关注解

    @SpringBootApplication 背后到底是什么? 

    @SpringBootConfiguration 

    @EnableAutoConfiguration

    @ComponentScan

    @Configuration

    @Configuration和@Component的区别是什么?

    SpringApplication.run做了哪些事?

    @Bean

    异常处理相关注解

             为什么要用统一异常接收?

    @ControllerAdvice

    @ResponseBody

    @Controller、@Service、@Repository、@Component

     面试题:将一个类声明为 Spring 的 bean 的注解有哪些?

    @RequestMapping

    @CrossOrigin

    @Autowired

    @PostConstruct

    @Transactional

     @Transactional注解可以作用于哪些地方?

    @Transactional注的常用属性

    当声明式事务 @Transactional 遇到以下场景时,事务会失效:


    启动类相关注解

    项目中的启动类

    @SpringBootApplication 背后到底是什么? 

    @SpringBootApplication注解实际上是SpringBoot提供的一个复合注解,看源码:

    很清楚,其是一个合成体,但其中最重要的三个注解分别是:

    • @SpringBootConfiguration

    • @EnableAutoConfiguration

    • @ComponentScan

     如果不怕麻烦,在 SpringBoot 应用的启动类上用这个三个注解代替@SpringBootApplication 注解发现也是没问题的:

    1. @SpringBootConfiguration
    2. @EnableAutoConfiguration
    3. @ComponentScan
    4. public class TestSpringBootApplication {
    5. ...
    6. }

    @SpringBootConfiguration 

    这说明 @SpringBootConfiguration 也是来源于 @Configuration,二者功能都是将当前类标注为配置类,并将当前类里以 @Bean 注解标记的方法的实例注入到srping容器中,实例名即为方法名。

    至于@Configuration,作用是配置Spring容器,也即 JavaConfig 形式的 Spring IoC 容器的配置类所使用。

    @EnableAutoConfiguration

    @EnableAutoConfiguration 注解启用自动配置,其可以帮助 SpringBoot 应用将所有符合条件的 @Configuration 配置都加载到当前 IoC 容器之中,可以简要用图形示意如下:

    从宏观一点的角度 概括总结 上述这一过程那就是:

    从 ClassPath下扫描所有的 META-INF/spring.factories 配置文件,并将spring.factories 文件中的 EnableAutoConfiguration 对应的配置项通过反射机制实例化为对应标注了 @Configuration 的形式的IoC容器配置类,然后注入IoC容器。

    @ComponentScan

    @ComponentScan 对应于XML配置形式中的 ,用于将一些标注了特定注解的bean定义批量采集注册到Spring的IoC容器之中,这些特定的注解大致包括:

    • @Controller
    • @Entity
    • @Component
    • @Service
    • @Repository

    等等

    对于该注解,还可以通过 basePackages 属性来更细粒度的控制该注解的自动扫描范围,比如:

    @ComponentScan(basePackages = {"cn.codesheep.controller","cn.codesheep.entity"})

     此部分参考此文章https://www.jianshu.com/p/9dc7a385d19e --@SpringBootApplication注解背后的三体结构探秘

    此部分参考文章:

    一个面试题引起的SpringBoot启动解析 - 掘金-----很不错

    Spring容器启动流程(源码解读) - 掘金---果然很源码,看着很懵

    SpringBoot 应用程序启动过程探秘 - 掘金---细致总结

    SpringBoot 中启动 Tomcat 流程 - 掘金---Tomcat相关

    从Spring启动过程来理解IoC、AOP和bean的生命周期 - 掘金----宏观学习

    @Configuration

    由于上面的@SpringBootConfiguration注解底层主要使用的是@Configuration,那么,再来深入理解下@Configuration。

    JavaConfig形式的Spring Ioc容器的配置类使用的那个@Configuration,SpringBoot社区推荐使用基于JavaConfig的配置形式,所以,这里的启动类标注了@Configuration之后,本身其实也是一个IoC容器的配置类。

    @Configuration的主要目的是搭配@Bean注解替代XML配置文件来向Spring容器注入Bean

    任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类。
    任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id。

    可以看到@Configuration的底层是@Component,但是两者又有不同

    @Configuration和@Component的区别是什么?

    这两个注解都是配置类注解,作用于类上,申明该类为组件。不同之处在于:

    1、@Component是一个元注解,可以注解其他类注解。@Configuration注解里面也是被@Component注解修饰的。

    2、bean设置的类属性不同。

    • 如果是 @Configuration 并且属性 proxyBeanMethods 为 true(默认的),则为 full
    • 如果是 @Component @ComponentScan @Import @ImportSource 则为 lite

    3、返回bean实例不同。

    • @Configuration 注解修饰的类,并且该注解中的 proxyBeanMethods 属性的值为 true(默认的),则会使用cglib动态代理,为这个 bean 创建一个代理类,该代理类会拦截所有被 @Bean 修饰的方法,在拦截的方法逻辑中,会从容器中返回所需要的单例对象。
    • @Component 注解修饰的类,则不会为这个 bean 创建一个代理类。 那么我们就会直接执行用户的方法,所以每次都会返回一个新的对象。

    Spring注解中@Configuration、@Component、@Bean的用法区别 - 掘金

    此部分参考的好文

    一个面试题引起的SpringBoot启动解析 - 掘金-----有一部分参考

    原创 | 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration - 掘金----这篇最棒

    Spring注解中@Configuration、@Component、@Bean的用法区别 - 掘金

    Spring中@Component和@Configuration的区别 - 掘金

    SpringApplication.run做了哪些事?

    SpringApplication.run一共做了两件事,分别是

    • 创建SpringApplication对象

    • 利用创建好的SpringApplication对象,调用run方法

    1.创建SpringApplication对象

    这个类中封装了程序的入口

    2.调用run方法

    【肥朝】面试官问我,SpringApplication.run做了哪些事? - 掘金-----简单理解版

    SpringBoot 应用程序启动过程探秘 - 掘金----深入理解版

    总结:

    SpringApplication.run一共做了两件事,一件是创建SpringApplication对象,在该对象初始化时,找到配置的事件监听器,并保存起来.第二件事就是运行run方法,此时会将刚才保存的事件监听器根据当前时机触发不同的事件,比如容器初始化,容器创建完成等.同时也会刷新IoC容器,进行组件的扫描、创建、加载等工作。

    @Bean

    @Bean 注解 - 掘金

    异常处理相关注解

    为什么要用统一异常接收?

    通常在service层抛异常,涉及到事务时不会进行try-catch,需要在controller里处理异常。即使能够进行try-catch的地方也需要统一返回格式,造成重复代码很多,可读性比较差。所以在项目中进行统一异常处理;具体做法是:直接在service层抛出异常,controller中返回正常的结果,当将异常抛到controller时,由标注了@ControllerAdvice的类对异常进行处理(需要配合@ExceptionHandler使用)。可以对异常进行统一处理,规定返回的json格式或是跳转到一个错误页面。

    返回对应请求的返回处理结果 "success" 或 "fail"

    若status = success,则data内返回前端需要的json数据
    若status = fail,则data内使用通用的错误码格式

    @ControllerAdvice

    @ControllerAdvice是一个特殊的@Component,用于标识一个类,这个类中被以下三种注解标识的方法:

    1. 全局异常处理(@ExceptionHandler)
    2. 全局数据绑定(@ModelAttribute)
    3. 全局数据预处理(@InitBinder)

    Spring进阶之@ControllerAdvice与统一异常处理 - 掘金

    项目中主要用于全局异常处理,这里就只介绍这块的内容;全局异常处理时,@ControllerAdvice配合@ExceptionHandler 注解用来指明异常的处理类型,使用很简单,在类上面添加ControllerAdvice注解,在方法上面添加ExceptionHandler注解,就可以在方法里处理相应的异常信息了。即如果这里指定NullpointerException,则数组越界异常就会进到这个方法中来。

    @ExceptionHandler(Exception.class)

    项目中是@ExceptionHandler(Exception.class),那么Exception体系下的异常类都会进入到此异常接收类中。

    SpringBoot源码解析-ExceptionHandler处理异常的原理 - 掘金----原理刨析(未学习)

    @ResponseBody

    @ResponseBody注解告诉控制器,返回的对象需要自动化序列成JSON,并通过HttpResponseBody返回给客户端,在项目中主要是发生异常时不需要进行页面跳转而是直接返回数据;这个时候就需要在方法上,添加注解:@ResponseBody

    默认情况下,使用@ResponseBody返回的数据只能是String类型,其它类型返回时会出现异常;

    在项目中添加了JSON格式的转换器-----jackson框架依赖;Jackson库实现了Java对象和JSON的相互转换,保证返回给前端JSON数据。

    Java分享SpringMVC@ResponseBody注解 - 掘金

    SpringMVC中@RequestBody和@ResponseBody两个注解的区别 - 掘金

    RequestBody和ResponseBody踩坑 - 掘金

    @RequestBody和主要是用来接收前端传给后端的json数据;参数放在请求体中,传入后台需要用@RequestBody进行接收;

    @RequestParam

    常见的接口请求类型和@RequestBody、@RequestParam的使用 - 掘金

    @Controller、@Service、@Repository、@Component

    @Component 

    通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注;spring扫描的时候扫描的是这个注解。

    标记@Component的类在spring的beanName中是类首字母小写,其余字母都一样。因为其它几个常用典型注解也是Component,所以他们与Component有相同的beanName命名方式。

    @Controller 

    对应 Spring MVC 控制层,主要用来接受用户请求并调用 Service 层返回数据给前端页面;它通常与@RequestMapping 注解一起使用。允许实现类能够被自动扫描到。

    @Service 

    应用的业务逻辑通常在service层实现,因为我们一般使用@Service注解标记这个类属于业务逻辑层。允许实现类通过类路径的扫描扫描到。

    @Repository 

    对应持久层即 Dao 层,主要用于数据库相关操作。允许实现类能够被自动扫描到。

    总结:

    上面四个注解标记的类都能够通过@ComponentScan 扫描到,上面四个注解最大的区别就是使用的场景和语义不一样,比如你定义一个Service类想要被Spring进行管理,你应该把它定义为@Service 而不是@Controller因为我们从语义上讲,@Service更像是一个服务的类,而不是一个控制器的类,@Component通常被称作组件,它可以标注任何你没有严格予以说明的类,比如说是一个配置类,它不属于MVC模式的任何一层,这个时候你更习惯于把它定义为 @Component。@Controller,@Service,@Repository 的注解上都有@Component,所以这三个注解都可以用@Component进行替换。项目小的时候对这些注解没有特别的区分,但项目如果变得越来越大,那么就要划分的细致一些有一定的规则才方便大家的维护。

     面试题:将一个类声明为 Spring 的 bean 的注解有哪些?

    • @Component :通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注;Spring扫描的时候扫描的是这个注解。

    • @Configuration :声明该类为一个配置类,可以在此类中声明一个或多个 @Bean 方法。

    • @Controller :对应 Spring MVC 控制层,主要用来接受用户请求并调用 Service 层返回数据给前端页面。

    • @Service :对应服务层,主要设计一些复杂的逻辑,需要用到 Dao 层。

    • @Repository :对应持久层即 Dao 层,主要用于数据库相关操作。

    @RequestMapping

    @RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一,这个注解会将 HTTP 请求映射到 SpringMVC 和 REST 控制器的处理方法上。@RequestMapping用来匹配客户端发送的请求,可以在方法上使用,也可以在类上使用。

    方法:表示用来匹配要处理的请求

    类上:表示为当前类的所有方法的请求地址添加一个前置路径,访问的时候必须要添加此路径。

    超详细 Spring @RequestMapping 注解使用技巧 - 掘金----这篇棒

    2、SpringMVC:请求处理之@RequestMapping - 掘金

    SpringMVC的@RequestMapping用法 - 掘金--不错

    @CrossOrigin

    SpringMVC提供了注解 @CrossOrigin 解决跨域问题,在方法上方添加该注解即可,注解里加入发出请求的URL路径,就实现了前后端分离中的跨域请求。

    同源策略

    同源策略是浏览器的一个安全功能,同源,指的是两个URL的协议,域名,端口相同。浏览器出于安全方面的考虑,不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。

    那些不受同源策略的限制:

    1. 页面中的跳转、表单提交不会受到同源策略限制的。
    2. 静态资源引入也不会受到同源策略限制。如嵌入到页面中的