目录
@SpringBootApplication 背后到底是什么?
@Configuration和@Component的区别是什么?
@Controller、@Service、@Repository、@Component
面试题:将一个类声明为 Spring 的 bean 的注解有哪些?
当声明式事务 @Transactional 遇到以下场景时,事务会失效:
项目中的启动类

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

很清楚,其是一个合成体,但其中最重要的三个注解分别是:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
如果不怕麻烦,在 SpringBoot 应用的启动类上用这个三个注解代替@SpringBootApplication 注解发现也是没问题的:
- @SpringBootConfiguration
- @EnableAutoConfiguration
- @ComponentScan
- public class TestSpringBootApplication {
- ...
- }

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

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

从宏观一点的角度 概括总结 上述这一过程那就是:
从 ClassPath下扫描所有的 META-INF/spring.factories 配置文件,并将spring.factories 文件中的 EnableAutoConfiguration 对应的配置项通过反射机制实例化为对应标注了 @Configuration 的形式的IoC容器配置类,然后注入IoC容器。
@ComponentScan 对应于XML配置形式中的
等等
对于该注解,还可以通过 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的生命周期 - 掘金----宏观学习
由于上面的@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,但是两者又有不同

这两个注解都是配置类注解,作用于类上,申明该类为组件。不同之处在于:
1、@Component是一个元注解,可以注解其他类注解。@Configuration注解里面也是被@Component注解修饰的。
2、bean设置的类属性不同。
3、返回bean实例不同。
Spring注解中@Configuration、@Component、@Bean的用法区别 - 掘金
此部分参考的好文
一个面试题引起的SpringBoot启动解析 - 掘金-----有一部分参考
原创 | 我被面试官给虐懵了,竟然是因为我不懂Spring中的@Configuration - 掘金----这篇最棒
Spring注解中@Configuration、@Component、@Bean的用法区别 - 掘金
Spring中@Component和@Configuration的区别 - 掘金
SpringApplication.run一共做了两件事,分别是

创建SpringApplication对象
利用创建好的SpringApplication对象,调用run方法
1.创建SpringApplication对象
这个类中封装了程序的入口


2.调用run方法


【肥朝】面试官问我,SpringApplication.run做了哪些事? - 掘金-----简单理解版
SpringBoot 应用程序启动过程探秘 - 掘金----深入理解版
SpringApplication.run一共做了两件事,一件是创建SpringApplication对象,在该对象初始化时,找到配置的事件监听器,并保存起来.第二件事就是运行run方法,此时会将刚才保存的事件监听器根据当前时机触发不同的事件,比如容器初始化,容器创建完成等.同时也会刷新IoC容器,进行组件的扫描、创建、加载等工作。
通常在service层抛异常,涉及到事务时不会进行try-catch,需要在controller里处理异常。即使能够进行try-catch的地方也需要统一返回格式,造成重复代码很多,可读性比较差。所以在项目中进行统一异常处理;具体做法是:直接在service层抛出异常,controller中返回正常的结果,当将异常抛到controller时,由标注了@ControllerAdvice的类对异常进行处理(需要配合@ExceptionHandler使用)。可以对异常进行统一处理,规定返回的json格式或是跳转到一个错误页面。

返回对应请求的返回处理结果 "success" 或 "fail"
若status = success,则data内返回前端需要的json数据
若status = fail,则data内使用通用的错误码格式

@ControllerAdvice是一个特殊的@Component,用于标识一个类,这个类中被以下三种注解标识的方法:
@ExceptionHandler)@ModelAttribute)@InitBinder)Spring进阶之@ControllerAdvice与统一异常处理 - 掘金
项目中主要用于全局异常处理,这里就只介绍这块的内容;全局异常处理时,@ControllerAdvice配合@ExceptionHandler 注解用来指明异常的处理类型,使用很简单,在类上面添加ControllerAdvice注解,在方法上面添加ExceptionHandler注解,就可以在方法里处理相应的异常信息了。即如果这里指定NullpointerException,则数组越界异常就会进到这个方法中来。
@ExceptionHandler(Exception.class)
项目中是@ExceptionHandler(Exception.class),那么Exception体系下的异常类都会进入到此异常接收类中。
SpringBoot源码解析-ExceptionHandler处理异常的原理 - 掘金----原理刨析(未学习)
@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的使用 - 掘金
通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注;spring扫描的时候扫描的是这个注解。
标记@Component的类在spring的beanName中是类首字母小写,其余字母都一样。因为其它几个常用典型注解也是Component,所以他们与Component有相同的beanName命名方式。
对应 Spring MVC 控制层,主要用来接受用户请求并调用 Service 层返回数据给前端页面;它通常与@RequestMapping 注解一起使用。允许实现类能够被自动扫描到。
应用的业务逻辑通常在service层实现,因为我们一般使用@Service注解标记这个类属于业务逻辑层。允许实现类通过类路径的扫描扫描到。
对应持久层即 Dao 层,主要用于数据库相关操作。允许实现类能够被自动扫描到。
上面四个注解标记的类都能够通过@ComponentScan 扫描到,上面四个注解最大的区别就是使用的场景和语义不一样,比如你定义一个Service类想要被Spring进行管理,你应该把它定义为@Service 而不是@Controller因为我们从语义上讲,@Service更像是一个服务的类,而不是一个控制器的类,@Component通常被称作组件,它可以标注任何你没有严格予以说明的类,比如说是一个配置类,它不属于MVC模式的任何一层,这个时候你更习惯于把它定义为 @Component。@Controller,@Service,@Repository 的注解上都有@Component,所以这三个注解都可以用@Component进行替换。项目小的时候对这些注解没有特别的区分,但项目如果变得越来越大,那么就要划分的细致一些有一定的规则才方便大家的维护。




@Component :通用的注解,可标注任意类为 Spring 的组件。如果一个 Bean 不知道属于哪个层,可以使用 @Component 注解标注;Spring扫描的时候扫描的是这个注解。
@Configuration :声明该类为一个配置类,可以在此类中声明一个或多个 @Bean 方法。
@Controller :对应 Spring MVC 控制层,主要用来接受用户请求并调用 Service 层返回数据给前端页面。
@Service :对应服务层,主要设计一些复杂的逻辑,需要用到 Dao 层。
@Repository :对应持久层即 Dao 层,主要用于数据库相关操作。
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一,这个注解会将 HTTP 请求映射到 SpringMVC 和 REST 控制器的处理方法上。@RequestMapping用来匹配客户端发送的请求,可以在方法上使用,也可以在类上使用。
方法:表示用来匹配要处理的请求
类上:表示为当前类的所有方法的请求地址添加一个前置路径,访问的时候必须要添加此路径。
超详细 Spring @RequestMapping 注解使用技巧 - 掘金----这篇棒
2、SpringMVC:请求处理之@RequestMapping - 掘金
SpringMVC的@RequestMapping用法 - 掘金--不错
SpringMVC提供了注解 @CrossOrigin 解决跨域问题,在方法上方添加该注解即可,注解里加入发出请求的URL路径,就实现了前后端分离中的跨域请求。
同源策略是浏览器的一个安全功能,同源,指的是两个URL的协议,域名,端口相同。浏览器出于安全方面的考虑,不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源。
那些不受同源策略的限制: