上一篇文章说了说Spring容器的做用,此次趁热打铁,看看Spring Boot中它是怎么起做用的。html
有了Spring容器以后,开发的模式简化了不少,你的注意力基本只须要集中在编写Bean上,好比@Controller类呀,@Service类呀,@Repository类呀等等。你新建了一个Spring Boot应用以后,随便编写一个控制器(Controller),他就能够用来处理网络请求了。按理说,一个控制器成为容器中的Bean,得有@ComponentScan来扫描呀,可是新建的应用也没看到有配置类,更不用说依靠在其之上的@ComponentScan注解了。这一些都要从@SpringBootApplication提及。git
上图是很常见的Application类,用Spring Initializr生成的项目都有。它有个@SpringBootApplication注解,这个注解提供了Spring Boot的不少关键特性。咱们打开SpringBootApplication的源码看一看:github
@SpringBootApplication是个组合注解(composed annotation),用它就至关于同时用了下面三个注解:spring
Spring提供的不少注解都是元注解,组合注解就是由一个或者多个元注解组合成的。比方说@RestController,你写纯API服务的时候,控制器通常都用上它,它是由@Controller和@ResponseBody组合而成的,你直接把@RestController替换成这两个,是能够的,他们是等效的。网络
若是你细心的话,会发现@Controller也是一个组合注解,元注解是@Component,因此说为何组件扫描能扫描到@Controller,缘由就在这里。app
一个注解多是元注解,也多是组合注解,它俩只是个相对的概念。实际开发中,若是你的一个组件类加了好多注解,不妨本身去建立一个新的组合注解,这样更清晰简洁。更多相关内容,你能够看看Spring文档里关于元注解和组合注解的详细说明。spring-boot
废了这么多口舌,我就是想告诉你@SpringBootApplication目的就是为了方便地引入它的三个元注解。post
刚才咱们说到了@ComponentScan,它用来告诉Spring容器去扫描组件,可是去哪里扫描呢?它有一个String[]类型的注解参数basePackages,能够传入须要扫描的路径,若是你不传,那就以当前类的包做为路径。因此这么一来,你的Application类在哪一个包里,自动扫描就在哪一个包里扫。你只要在这个包或者子包里编写@Controller类或者其余@Component类,都会被扫到的。假设你的Application类所在的包为com.fookwood.demo,那建议你全部的代码都放这个包下,免得由于组件没放入容器而出错。gradle
咱们知道@ComponentScan都是跟着配置类一块儿出现的,可是没见哪里有@Configuration呀?由于有@SpringBootConfiguration了,他是个组合注解,把@Configuration带来了。话说我找了不少资料,没有发现@SpringBootConfiguration到底有什么独特做用,它的注释上说一个程序一般只须要一个@SpringBootConfiguration就好了,并且大部分都是从@SpringBootApplication获取的。那干脆无论了,就当他是个@Configuration吧。ui
最后,该讨论下@EnableAutoConfiguration了。他开启了Spring Boot中最重要的特性—自动配置,自动配置能够根据你引入的依赖自动生成Bean等。大部分依赖都有对应一个叫作*AutoConfiguration的类,好比GSON有一个对应的GsonAutoConfiguration类:
看图,他是一个正常的配置类,有@Configuration注解,可是呢,它的方法提供的Bean并非直接加到容器里的,而是须要知足必定条件才行。条件呢,经过@Conditional* 注解提供,GsonAutoConfiguration使用了@ConditionalOnClass注解,它的参数是Gson.class,意思就是,当类路径中有Gson这个类的时候,GsonAutoConfiguration才是一个真正的配置类。图中的gsonBuilder方法新建了一个GsonBuilder对象,若是容器里没有这个类型的Bean,就使用新建的这个对象。图中的gson方法,新建了一个Gson对象,若是容器里没有Gson类型的Bean,就把这个对象放进去。
因此说,一旦你在build.gradle中添加了GSON的依赖,那么你就能够直接在本身的代码里引入Gson对象了,省事儿不?你要是想定义本身的Gson对象,固然能够,你能够在本身的配置类,添加你本身的GsonBuilder对象或者Gson对象,这样的话,自动配置判断容器里已经有了,@Conditional*的条件不成立,就不本身搞了。
再提一句吧,虽然你的Application类(好比本文最上面的WhatEverApplication)也是一个配置类,你能够添加方法来建立新的Bean,不过我不喜欢这么这么作,我一般是新建单独的配置类,好比新建一个名为WebConfig的类,在这个类里定义Web开发相关的Bean。