点击蓝色“程序员的时光 ”关注我 ,标注“星标”,及时阅读最新技术文章
写在前面:
小伙伴儿们,大家好!上一篇介绍了入门学习SpringBoot——这年头还不会SpringBoot?
后续会持续更新,敬请期待!
思维导图:
1,SpringBoot原理分析;
1.1,起步依赖原理分析;
分析spring-boot-starter-parent
:
找到pom.xml中的spring-boot-starter-parent
,Crtl+点击跳转到了spring-boot-starter-parent
的pom.xml,xml配置如下(部分摘录):
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.3.1.RELEASE</version>
</parent>
再按住Ctrl点击spring-boot-dependencies
,会再次跳转到spring-boot-starter-dependencies
的 pom.xml,xml配置如下(部分摘录):
<properties>
<activemq.version>5.15.12</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.80</appengine-sdk.version>
<artemis.version>2.12.0</artemis.version>
<aspectj.version>1.9.5</aspectj.version>
<assertj.version>3.16.1</assertj.version>
<atomikos.version>4.0.6</atomikos.version>
<awaitility.version>4.0.3</awaitility.version>
<bitronix.version>2.1.4</bitronix.version>
<build-helper-maven-plugin.version>3.1.0</build-helper-maven-plugin.version>
<byte-buddy.version>1.10.11</byte-buddy.version>
<caffeine.version>2.8.4</caffeine.version>
<cassandra-driver.version>4.6.1</cassandra-driver.version>
<classmate.version>1.5.1</classmate.version>
<commons-codec.version>1.14</commons-codec.version>
<commons-dbcp2.version>2.7.0</commons-dbcp2.version>
<commons-lang3.version>3.10</commons-lang3.version>
</properties>
从上面的spring-boot-starter-dependencies
的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管 理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent
后已经具备版本锁定等配置了。所以 起步依赖的作用就是进行依赖的传递。
分析spring-boot-starter-web
:
找到pom.xml中的spring-boot-starter-web
,Crtl+点击跳转到了spring-boot-starter-web
的pom.xml,xml配置如下(部分摘录):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.3.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-json</artifactId>
<version>2.3.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<version>2.3.1.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<scope>compile</scope>
</dependency>
</dependencies>
从上面我们可以看到其中有json,tomcat以及spring相关的依赖,spring-boot-starter-web
就是将web开发要使用的 spring-web
、spring-webmvc
等坐标进行了打包,这样我们的工程只要引入spring-boot-starter-web
起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用。
1.2,自动配置原理解析;
分析@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}
)}
)
其中,
@SpringBootConfiguration:等同与@Configuration,既标注该类是Spring的一个配置类 @EnableAutoConfiguration:SpringBoot自动配置功能开启
分析@EnableAutoConfiguration
:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
其中:
@Import(AutoConfigurationImportSelector.class)
导入了AutoConfigurationImportSelector类
分析@AutoConfigurationImportSelector
:
SpringFactoriesLoader.loadFactoryNames 方法的作用就是从META-INF/spring.factories文件中读取指定 类对应的类名称列表;
其实,说了这么多,SpringBoot中配置文件存在大量的以Configuration为结尾的类名称,这些类就是存有自动配置信息的类,而 SpringApplication在获取这些类名后再加载。
2,SpringBoot项目属性配置;
2.1,项目内置属性;
我们前面运行成功之后的端口是8080,这个是可以自定义修改的;我们来看看SpringBoot中的application.properties
配置文件:
#项目内置属性,端口号为8888,路径为sb
server.port=8888
server.servlet.context-path=/sb
这样我们在访问Controller类的时候就必须用上述配置信息:
2.2,项目自定义属性;
我们也可以添加自定义的属性;
#项目内置属性,端口号为8888,路径为sb
server.port=8888
server.servlet.context-path=/sb
#项目自定义属性
helloSpring=springboot你好呀呀呀
我们在Controller类中需要定义我们写的hellospring
;
@RestController
public class Controller {
/*用Value类注入使用*/
@Value("${helloSpring}")
private String helloSpring;
@RequestMapping("/springboot")
public String startSpringBoot() {
return helloSpring;
}
}
运行:
注意,这里如果出现乱码的话,我们需要到IDEA中修改一下配置:
然后修改一下application.properties
配置文件,再重新运行就可以了~
2.3,ConfigurationProperties 配置;
像前面所说的那样,如果我自定义有许多配置的话,那每一个都加配置的话就太麻烦了,这里可以封装使用(统一附上前缀);
在application.properties
文件中,我们写jdbc相关的配置:
#项目内置属性,端口号为8888,路径为sb
server.port=8888
server.servlet.context-path=/sb
#项目自定义属性
helloSpring=springboot你好呀呀呀
mysql.jdbcName=com.mysql.jdbc.Driver
mysql.dbUrl=jdbc:mysql://localhost:3306/db_boot
mysql.userName=root
mysql.password=123456
我们新建一个properties类:
package com.java.springboot.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "mysql")
public class MysqlProperties {
private String jdbcName;
private String dbUrl;
private String userName;
private String password;
public String getJdbcName() {
return jdbcName;
}
public void setJdbcName(String jdbcName) {
this.jdbcName = jdbcName;
}
public String getDbUrl() {
return dbUrl;
}
public void setDbUrl(String dbUrl) {
this.dbUrl = dbUrl;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
注意这里我们要在pom.xml文件里面添加spring-boot-configuration-processor
这个依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
然后在Controller类中我们直接注入就可以了:
package com.java.springboot;
import com.java.springboot.properties.MysqlProperties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RestController
public class Controller {
/*用Value类注入使用*/
@Value("${helloSpring}")
private String helloSpring;
@Resource
private MysqlProperties mysqlProperties;
@RequestMapping("/springboot")
public String startSpringBoot() {
return helloSpring;
}
@RequestMapping("/jdbc")
public String say() {
return "mysql.jdbcName:"+mysqlProperties.getJdbcName()+"<br/>"
+"mysql.dbUrl:"+mysqlProperties.getDbUrl()+"<br/>"
+"mysql.userName:"+mysqlProperties.getUserName()+"<br/>"
+"mysql.password:"+mysqlProperties.getPassword()+"<br/>";
}
}
我们运行:
可见,非常简单方便!
往期推荐
好了,今天就先分享到这里了,下期继续给大家带来SpringBoot后续内容!更多干货、优质文章,欢迎关注我的原创技术公众号~
文章都看完了不点个 吗