Spring Boot
遵循约定大于配置的思想为我们省去了繁杂的XML配置,其为我们提供了许多诸如:spring-boot-starter-web
、spring-boot-starter-data-jpa
、spring-boot-starter-data-redis
等常用的Starter
组件,使得我们整合各种常用组件时显得非常简便快捷,那么这个Starter
为我们做了什么工作?让我们省去了各种繁杂的整合过程。
Spring Boot Starter是什么?
我们在使用Spring Boot
开发应用的时候,经常会引入这样的包:
1 | <dependency> |
其实它们只是整合了当前模块需要的依赖库以及封装了当前组件的常规使用配置使其自动装配,使得我们在使用相应的starter
组件的时候省去了我们手动配置的繁琐工作。按道理来说应该先看官方的starter
组件源码,但是呢,之前在Spring Boot整合Mybatis Plus和Druid和Spring Boot 2.X基于Mybaits-Plus实现多数据源中都用到了druid-spring-boot-starter这个starter
组件,所以我们可以借此机会来看看它,因为自定义开发starter
组件也都是按照官方的规范来做的。
开发Spring Boot Starter要点
自己开发一个Starter
一般需要以下几个步骤:
- 新建项目,引入Starter所要用到的依赖包
- 组件配置类,指定配置前缀以及配置默认值设置
- 自动装配类,让组件进行自动装配;
- spring.factories文件,指定
Starter
的自动装配类的路径;
初探druid-spring-boot-starter
首先去下载druid源码,导入到IDEA中,可以看到这样的目录结构,
这里我们先来看看pom.xml
,会发现里面有两个包:
1 | <dependency> |
- spring-boot-configuration-processor:用于解析传统的xml或properties配置文件,Spring Boot默认使用的是yml
- spring-boot-autoconfigure:自动装配组件,实现自动扫描装载
完整的
pom.xml
大家就去github中查看。druid-spring-boot-starter的配置类DruidStatProperties
这个类是1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178@ConfigurationProperties("spring.datasource.druid")
public class DruidStatProperties {
private String[] aopPatterns;
private StatViewServlet statViewServlet = new StatViewServlet();
private WebStatFilter webStatFilter = new WebStatFilter();
public String[] getAopPatterns() {
return aopPatterns;
}
public void setAopPatterns(String[] aopPatterns) {
this.aopPatterns = aopPatterns;
}
public StatViewServlet getStatViewServlet() {
return statViewServlet;
}
public void setStatViewServlet(StatViewServlet statViewServlet) {
this.statViewServlet = statViewServlet;
}
public WebStatFilter getWebStatFilter() {
return webStatFilter;
}
public void setWebStatFilter(WebStatFilter webStatFilter) {
this.webStatFilter = webStatFilter;
}
public static class StatViewServlet {
/**
* Enable StatViewServlet, default false.
*/
private boolean enabled;
private String urlPattern;
private String allow;
private String deny;
private String loginUsername;
private String loginPassword;
private String resetEnable;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getUrlPattern() {
return urlPattern;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
public String getAllow() {
return allow;
}
public void setAllow(String allow) {
this.allow = allow;
}
public String getDeny() {
return deny;
}
public void setDeny(String deny) {
this.deny = deny;
}
public String getLoginUsername() {
return loginUsername;
}
public void setLoginUsername(String loginUsername) {
this.loginUsername = loginUsername;
}
public String getLoginPassword() {
return loginPassword;
}
public void setLoginPassword(String loginPassword) {
this.loginPassword = loginPassword;
}
public String getResetEnable() {
return resetEnable;
}
public void setResetEnable(String resetEnable) {
this.resetEnable = resetEnable;
}
}
public static class WebStatFilter {
/**
* Enable WebStatFilter, default false.
*/
private boolean enabled;
private String urlPattern;
private String exclusions;
private String sessionStatMaxCount;
private String sessionStatEnable;
private String principalSessionName;
private String principalCookieName;
private String profileEnable;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public String getUrlPattern() {
return urlPattern;
}
public void setUrlPattern(String urlPattern) {
this.urlPattern = urlPattern;
}
public String getExclusions() {
return exclusions;
}
public void setExclusions(String exclusions) {
this.exclusions = exclusions;
}
public String getSessionStatMaxCount() {
return sessionStatMaxCount;
}
public void setSessionStatMaxCount(String sessionStatMaxCount) {
this.sessionStatMaxCount = sessionStatMaxCount;
}
public String getSessionStatEnable() {
return sessionStatEnable;
}
public void setSessionStatEnable(String sessionStatEnable) {
this.sessionStatEnable = sessionStatEnable;
}
public String getPrincipalSessionName() {
return principalSessionName;
}
public void setPrincipalSessionName(String principalSessionName) {
this.principalSessionName = principalSessionName;
}
public String getPrincipalCookieName() {
return principalCookieName;
}
public void setPrincipalCookieName(String principalCookieName) {
this.principalCookieName = principalCookieName;
}
public String getProfileEnable() {
return profileEnable;
}
public void setProfileEnable(String profileEnable) {
this.profileEnable = profileEnable;
}
}
}Druid
的配置信息类,在类上使用了ConfigurationProperties
标识了配置前缀@ConfigurationProperties("spring.datasource.druid")
,该类会去获取类似如下结果的配置新信息1
2
3
4
5
6
7
8
9
10
11
12
13
14
15spring.datasource.druid.initial-size=
spring.datasource.druid.max-active=
spring.datasource.druid.min-idle=
spring.datasource.druid.max-wait=
spring.datasource.druid.pool-prepared-statements=
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=
spring.datasource.druid.max-open-prepared-statements= #和上面的等价
spring.datasource.druid.validation-query=
spring.datasource.druid.validation-query-timeout=
spring.datasource.druid.test-on-borrow=
spring.datasource.druid.test-on-return=
spring.datasource.druid.test-while-idle=
spring.datasource.druid.time-between-eviction-runs-millis=
spring.datasource.druid.min-evictable-idle-time-millis=
spring.datasource.druid.max-evictable-idle-time-millis=
自动装配类DruidDataSourceAutoConfigure
1 | @Configuration |
- @Configuration,该注解用于标识该类为一个配置类,并注入到IOC容器中
- @ConditionalOnClass在这里是需要
DruidDataSource
类才能被实例化 - @AutoConfigureBefore,在
DataSourceAutoConfiguration
之前加载该类 - @EnableConfigurationProperties注解的作用是使用
@ConfigurationProperties
注解的类生效。 - @Import,把未加标识注入到IOC容器的相应类注入到当前容器中
- @Bean(initMethod = “init”),在初始化bean时执行
init
方法
在装配DruidDataSourceAutoConfigure
类的时候,会执行DruidDataSource
类的init
对Druid
进行初始化。
spring.factories配置自动装配类
1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ |
让spring boot
知道我们的starter
组件的装配类路径,在启动时进行加载初始化。
这里并没有说到
Spring Boot Starter
的启动原理,只是找了一个组件来简单了解一下它为什么做了一些什么工作,后面我们再来深入一点了解一下spring boot
的启动原理。