目录
零.@SpringBootApplication
一.起步依赖
二.自动配置
三.自动配置的原理
1.装配常见方案
【1】方案1:@ComponentScan 组件扫描
【2】方案2:@Import 导入
【3】使用第三方依赖提供的 @EnableXxxxx注解
2.自动装配原理
3.实现starter
四.内置Tomcat
SpringBoot相比于Spring简化了开发,得益于它两个非常重要的功能:一个是起步依赖,一个是自动配置。
通过SpringBoot所提供的起步依赖,就可以大大的简化pom文件当中依赖的配置。
通过自动配置的功能就可以大大的简化在使用时Bean的配置类书写。
这样我们只需要引入程序开发时所需要的起步依赖,我们就可以直接使用其中的Bean了。
零.@SpringBootApplication
这个注解是Spring Boot项目的基石,创建SpringBoot项目之后会默认在主类加上。
@SpringBootApplication
public class SpringSecurityJwtGuideApplication {public static void main(java.lang.String[] args) {SpringApplication.run(SpringSecurityJwtGuideApplication.class, args);}
}
我们可以把 @SpringBootApplication看作是 @Configuration、@EnableAutoConfiguration、@ComponentScan 注解的集合。
package org.springframework.boot.autoconfigure;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {......
}package org.springframework.boot;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {}
根据 SpringBoot 官网,这三个注解的作用分别是:
(1)@EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
(2)@ComponentScan:扫描被@Component (@Repository,@Service,@Controller)注解的 bean,注解默认会扫描该类所在的包下所有的类。
(3)@Configuration:声明这个类是配置类。
并允许在 Spring 上下文中注册额外的 bean 或导入其他配置类。
这个注解是自动装配的核心,后面会讲到。
一.起步依赖
简单说就是我们只要引入一个starter依赖,与之相关的依赖jar包都会被引入。
注:starter是SpringBoot中常见项目名称,定义了很多该依赖所使用的其他依赖坐标,以达到简化配置的目的。
原理就是Maven的依赖传递。
例:
比如springboot-starter-web,这是web开发的起步依赖,在web开发的起步依赖当 中,就集成了web开发中常见的依赖:json、web、webmvc、tomcat等。我们只需要引入 这一个起步依赖,其他的依赖都会自动的通过Maven的依赖传递进来。
二.自动配置
概念:SpringBoot的自动配置就是当Spring容器启动后,一些配置类、bean对象就自动存入到了IOC容器 中,不需要我们手动去声明,从而简化了开发,省去了繁琐的配置操作。
解释:先回顾一下之前的spring注解开发的步骤
具体流程:定义Bean【第三方或自定义】->扫描进容器管理【扫描包或配置类】->依赖自动注入或按名称注入【普通类型可以通过配置文件注入】
简单说自动配置就是省略中间那一步。也就是我们自己扫描包(也就是配置)的过程,而采用自动配置。
之前要用@Component注册Bean,并且使用@ComponentScan之类的注解在配置类上对Bean进行扫描。
现在使用SpringBoot的@SpringBootApplication就实现了在启动时通过自动配置。将自定义Bean和第三方starter中的Bean自动装配到容器。
现在自定义的Bean的话只需要@Component和@Configuration注册Bean就可以了,后续不用管它。第三方starter的话只需要引入就可以通过@Autowired或@Resource注入Bean直接用。
附:在SpringBoot中@Configuration作用和@Component一样。
@Configuration一般用来声明配置类,可以使用@Component注解替代,不过使用注解@Configuration声明配置类更加语义化。
@Configuration public class AppConfig {@Beanpublic TransferService transferService() {return new TransferServiceImpl();} }
一般@Configuration用来配置第三方Bean,而@Component用来自定义Bean。
三.自动配置的原理
1.装配常见方案
我们可以试试自定义第三方Bean并引入依赖,会发现引入进来的第三方依赖当中的bean以及配置类为什么没有生效。
原因在我们之前讲解IOC的时候有提到过,在类上添加@Component注解来声明bean对象时,还需 要保证@ComponentScan注解能被Spring的组件扫描到。
SpringBoot项目中的@SpringBootApplication注解,具有包扫描的作用,但是它只会扫描启动类所在的当前包以及子包。
当前包:com.flyingpig, 第三方依赖中提供的包扫描不到。
那么如何解决以上问题的呢,那就是扫描我们第三方依赖的包。那怎么扫描呢,主要有三种方法。
【1】方案1:@ComponentScan 组件扫描
@SpringBootApplication
@ComponentScan({"com.flyingpig","com.example"}) //指定要扫描的包
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class,args);}
}
缺点: 1. 使用繁琐 2. 性能低
【2】方案2:@Import 导入
使用@Import导入的类会被Spring加载到IOC容器中
(1)引入类
@Import(TokenParser.class) //导入的类会被Spring加载到IOC容器中
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class,args);}
}
(2)导入配置类
@Configuration
public class HeaderConfig {@Beanpublic HeaderParser headerParser(){return new HeaderParser();}@Beanpublic HeaderGenerator headerGenerator(){return new HeaderGenerator();}
}
@Import(HeaderConfig.class) //导入配置类
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class,args);}
}
(3)导入ImportSelector接口实现类
public class MyImportSelector implements ImportSelector {public String[] selectImports(AnnotationMetadata importingClassMetadata) {//返回值字符串数组(数组中封装了全限定名称的类)return new String[]{"com.example.HeaderConfig"};}
}
@Import(MyImportSelector.class) //导入ImportSelector接口实现类
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class,args);}
}
上面两种方法对程序员比较很繁琐,不友好。
那我们如何我们不用自己指定要导入哪些bean对象和配置类了,让第三方依赖它自己来指定。
【3】使用第三方依赖提供的 @EnableXxxxx注解
在使用时只需在启动类上加上@EnableXxxxx注解即可
@EnableHeaderConfig //使用第三方依赖提供的Enable开头的注解
@SpringBootApplication
public class SpringbootWebConfig2Application {public static void main(String[] args) {SpringApplication.run(SpringbootWebConfig2Application.class,args);}
}
2.自动装配原理
在前面讲到的@SpringBootApplication注解中包含了:
【1】元注解(不再解释)
【2】@SpringBootConfiguration--底层是@Configuration注解,表明SpringBoot启动类就是一个配置类。
【3】@ComponentScan--用来进行组件扫描的,这里扫描启动类所在的包及其子包下所有Bean。
也就是说这个注解实现了自定义Bean的自动装配。
【4】@EnableAutoConfiguration--核心注解,实现第三方Bean自动装配。
底层封装了@Import注解(Import注解中指定了一个ImportSelector接口的实现类)
在实现类重写的selectImports()方法,读取当前项目下所有依赖jar包中META-INF/spring.factories、META-INF/spring/org.springframework.boot.autoconfigure.AutoConfigurat ion.imports两个文件里面定义的配置类(配置类中定义了@Bean注解标识的方法)。当SpringBoot程序启动时,就会加载配置文件当中所定义的配置类,并将这些配置类信息(类的全限定名)封装到String类型的数组中,最终通过@Import注解将这些配置类全部加载到Spring的IOC容器 中,交给IOC容器管理。
简单说就是第三方依赖定义配置类,然后通过底层的@Import注解调用接口实现类读取配置文件中的配置类,再读取其中的Bean进行配置。
而不用在代码中自己定义扫描了。
这些所有的自动配置类当中,所有的 bean都会加载到 spring 的 IOC 容器当中吗?
并不会。在声明 bean 的时候,通常会加上这么一类@Conditional 开头的注解。这个注解就是进行条件装配。所以SpringBoot非常的智能,它会根据 @Conditional 注解来进行条件装配。只有条件成立,它才会声明这 个bean,才会将这个 bean 交给 IOC 容器管理。
3.实现starter
在自定义一个起步依赖starter的时候,按照规范需要定义两个模块,一个用来实现起步依赖,一个用来实现自动配置:
1. starter模块(进行依赖管理[把程序开发所需要的依赖都定义在starter起步依赖中])
2. autoconfigure模块(自动配置) 将来在项目当中进行相关功能开发时,只需要引入一个起步依赖就可以了,因为它会将 autoconfigure自动配置的依赖给传递下来。
注:
SpringBoot官方starter命名: spring-boot-starter-xxxx
第三组织提供的starter命名: xxxx-spring-boot-starter
需求明确了,接下来我们再来分析一下具体的实现步骤:
第1步:创建自定义starter模块(进行依赖管理)
第2步:创建autoconfigure模块 在starter中引入autoconfigure (我们使用时只需要引入starter起步依赖即可)
第3步:在autoconfigure中完成自动配置
1. 定义一个自动配置类,在自动配置类中将所要配置的bean都提前配置好
2. 定义配置文件,把自动配置类的全类名定义在配置文件中
四.内置Tomcat
为什么我们之前书写的SpringBoot入门程序中,并没有把程序部署到Tomcat的webapps目录 下,也可以运行呢?
原因呢,是因为在我们的SpringBoot中,引入了web运行环境(也就是引入spring-boot-starter-web起步依赖),其内部已经集成了内置的Tomcat服务器。
我们可以通过IDEA开发工具右侧的maven面板中,就可以看到当前工程引入的依赖。其中已经将 Tomcat的相关依赖传递下来了,也就是说在SpringBoot中可以直接使用Tomcat服务器。