小伙伴们是否想起曾经被 SSM 整合支配的恐惧?相信很多小伙伴都是有过这样的经历的,一大堆配置问题,各种排除扫描,导入一个新的依赖又得添加新的配置。自从有了 Spring Boot 之后,咱们就起飞了!各种零配置开箱即用,而我们之所以开发起来能够这么爽,自动配置的功劳少不了,今天我们就一起来讨论一下 Spring Boot 自动配置原理,看完心里有个大概,不至于被面试官问的面红耳赤。
1. SpringBoot 源码常用注解
这部分主要讲一下 SpringBoot 源码中经常使用到的注解,以扫清后面阅读源码时候的障碍。
组合注解
当可能大量同时使用到几个注解到同一个类上,就可以考虑将这几个注解到别的注解上。被注解的注解我们就称之为组合注解。
- 元注解:可以注解到别的注解上的注解。
- 组合注解:被注解的注解我们就称之为组合注解。
@Value
@Value 就相当于传统 xml 配置文件中的 value 字段。
假设存在代码:
@Component public class Person {
@Value("i am name") private String name;
}
上面代码等价于的配置文件:
<bean class="Person"> <property name ="name" value="i am name"></property></bean>
我们知道配置文件中的 value 的取值可以是:
- 字面量
- 通过 ${key}方式从环境变量中获取值
- 通过 ${key}方式全局配置文件中获取值
-
{SpEL}
所以,我们就可以通过 @Value(${key})的方式获取全局配置文件中的指定配置项。
@ConfigurationProperties
如果我们需要取 N 个配置项,通过@Value的方式去配置项需要一个一个去取,这就显得有点 low 了。我们可以使用@ConfigurationProperties。标有@ConfigurationProperties的类的所有属性和配置文件中相关的配置项进行绑定。(默认从全局配置文件中获取配置值),绑定之后我们就可以通过这个类去访问全局配置文件中的属性值了。
@Import
@Import 注解支持导入普通 java 类,并将其声明成一个bean。主要用于将多个分散的 java config 配置类融合成一个更大的 config 类。
- @Import 注解在 4.2 之前只支持导入配置类。
- 在4.2之后 @Import 注解支持导入普通的 java 类,并将其声明成一个 bean。
@Import 三种使用方式
- 直接导入普通的 Java 类。
- 配合自定义的 ImportSelector 使用。
- 配合 ImportBeanDefinitionRegistrar 使用。
@Conditional
@Conditional 注释可以实现只有在特定条件满足时才启用一些配置。
除了自定义 Condition,Spring 还为我们扩展了一些常用的 Condition。
Java方面的架构资料,我这里刚好有一份,怎么领取→→→关注+转发 然后私信“架构资料” 即可领取
2. SpringBoot 自动配置原理
要了解SpringBoot自动化配置原理就要首先来看一下SpringbootDemoApplication.java。
@SpringBootApplication
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
我们可以看到这个类中最耀眼的就属@SpringBootApplication注解了,我们点进去看一下@SpringBootApplication的源码。
@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 { }
@Target,@Retention,@Documented,@Inherited四个注解属于元注解,与自动配置无关,我们不再讲解。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
是SpringBootApplication的核心注解,SpringBoot的启动类如果使用这三个注解也可以正常启动,SpringBoot帮我们做了简化。
@SpringBootConfiguration注解:
我们先来看看@SpringBootConfiguration注解的源码。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@SpringBootConfiguration 与@Configuration并没有任何区别,@Configuration可以标注当前类是一个配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到Spring IOC容器中。
@EnableAutoConfiguration注解:
The second class-level annotation is @EnableAutoConfiguration. This annotation tells Spring Boot to “guess” how you <br>will want to configure Spring, based on the jar dependencies that you have added. Since spring-boot-starter-web added Tomcat and Spring MVC, <br>the auto-configuration will assume that you are developing a web application and setup Spring accordingly.<br><br>
Starters and Auto-Configuration
Auto-configuration is designed to work well with “Starters”, but the two concepts are not directly tied. <br>You are free to pick-and-choose jar dependencies outside of the starters and Spring Boot will still do <br>its best to auto-configure your application.
这个注释告诉SpringBoot“猜”你将如何想配置Spring,基于你已经添加jar依赖项。如果spring-boot-starter-web已经添加Tomcat和Spring MVC,这个注释自动将假设您正在开发一个web应用程序并添加相应的spring设置。
自动配置被设计用来和“Starters”一起更好的工作,但这两个概念并不直接相关。您可以自由挑选starter依赖项以外的jar包,springboot仍将尽力自动配置您的应用程序。
spring通常建议我们将main方法所在的类放到一个root包下,@EnableAutoConfiguration(开启自动配置)注解通常都放到main所在类的上面,下面是一个典型的结构布局:
com
+- example
+- myproject
+- Application.java
|
+- domain
| +- Customer.java
| +- CustomerRepository.java
|
+- service
| +- CustomerService.java
|
+- web
+- CustomerController.java
这样@EnableAutoConfiguration可以从逐层的往下搜索各个加注解的类,例如,你正在编写一个JPA程序(如果你的pom里进行了配置的话),spring会自动去搜索加了@Entity注解的类,并进行调用
@ComponentScan注解:
@ComponentScan注解是我们非常熟悉的一个注解,@ComponentScan的功能就是自动扫描并加载符合条件的组件或Bean定义,最终将这些bean定义加载到当前使用的容器中。
通过以上三个注解,SpringBoot便完成了它的自动化配置,你看明白了吗?
至此,我们可以总结一下Spring Boot的自动化配置的实现:
网友评论