一、SpringBoot简介
1.1、Overview
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run". We take an opinionated view of the Spring platform and third-party libraries so you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.
Spring Boot使创建独立的、基于生产级Spring的应用程序变得很容易,您可以“直接运行”这些应用程序。我们对Spring平台和第三方库有自己的见解,这样您就可以轻松入门了。大多数Spring引导应用程序只需要很少的Spring配置。
1.2、Features
-
创建独立的Spring应用程序
-
直接嵌入Tomcat,Jetty或Undertow(无需部署WAR文件)
-
提供自以为是的“入门”依赖项以简化构建配置
-
尽可能自动配置Spring和第三方库
-
提供生产就绪功能,例如指标,运行状况检查和外部化配置
-
绝对没有代码生成,也不需要XML配置
二、SpringBoot快速入门
接下来利用SpringBoot搭建一个web工程,体会一下SpringBoot的魅力所在!使用IDEA创建一个Maven工程!
2.1、pom文件的配置
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.waggag.springboot</groupId>
<artifactId>SpringBoot_Demo</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--管理jdk的版本-->
<properties>
<java.version>1.8</java.version>
</properties>
<!--必须引入的父工程-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
2.2、启动类
1.第一种方式
//开启包扫描
@ComponentScan
//开启自动化配置
@EnableAutoConfiguration
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
2、第二种方式
//使用组合注解SpringBootApplication
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
2.3、编写Controller
package cn.waggag.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @description:
* @author: waggag
* @time: 2019/7/26 13:09
* @Company http://www.waggag.cn
*/
@Controller
public class DemoController {
@RequestMapping("/hello")
@ResponseBody
public String hello(){
return "Hello SpringBoot!";
}
}
2.4、运行访问
"D:\Program Files\Java\jdk1.8.0_221\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=8508:D:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_221\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar;D:\WorkSpace\IntelliJIDEA\SpringBoot\SpringBoot_Demo\target\classes;D:\repository\org\springframework\boot\spring-boot-starter-web\2.1.6.RELEASE\spring-boot-starter-web-2.1.6.RELEASE.jar;D:\repository\org\springframework\boot\spring-boot-starter\2.1.6.RELEASE\spring-boot-starter-2.1.6.RELEASE.jar;D:\repository\org\springframework\boot\spring-boot\2.1.6.RELEASE\spring-boot-2.1.6.RELEASE.jar;D:\repository\org\springframework\boot\spring-boot-autoconfigure\2.1.6.RELEASE\spring-boot-autoconfigure-2.1.6.RELEASE.jar;D:\repository\org\springframework\boot\spring-boot-starter-logging\2.1.6.RELEASE\spring-boot-starter-logging-2.1.6.RELEASE.jar;D:\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;D:\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;D:\repository\org\slf4j\slf4j-api\1.7.26\slf4j-api-1.7.26.jar;D:\repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;D:\repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;D:\repository\org\slf4j\jul-to-slf4j\1.7.26\jul-to-slf4j-1.7.26.jar;D:\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;D:\repository\org\springframework\spring-core\5.1.8.RELEASE\spring-core-5.1.8.RELEASE.jar;D:\repository\org\springframework\spring-jcl\5.1.8.RELEASE\spring-jcl-5.1.8.RELEASE.jar;D:\repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;D:\repository\org\springframework\boot\spring-boot-starter-json\2.1.6.RELEASE\spring-boot-starter-json-2.1.6.RELEASE.jar;D:\repository\com\fasterxml\jackson\core\jackson-databind\2.9.9\jackson-databind-2.9.9.jar;D:\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.0\jackson-annotations-2.9.0.jar;D:\repository\com\fasterxml\jackson\core\jackson-core\2.9.9\jackson-core-2.9.9.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.9\jackson-datatype-jdk8-2.9.9.jar;D:\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.9\jackson-datatype-jsr310-2.9.9.jar;D:\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.9\jackson-module-parameter-names-2.9.9.jar;D:\repository\org\springframework\boot\spring-boot-starter-tomcat\2.1.6.RELEASE\spring-boot-starter-tomcat-2.1.6.RELEASE.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.21\tomcat-embed-core-9.0.21.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.21\tomcat-embed-el-9.0.21.jar;D:\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.21\tomcat-embed-websocket-9.0.21.jar;D:\repository\org\hibernate\validator\hibernate-validator\6.0.17.Final\hibernate-validator-6.0.17.Final.jar;D:\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;D:\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;D:\repository\com\fasterxml\classmate\1.4.0\classmate-1.4.0.jar;D:\repository\org\springframework\spring-web\5.1.8.RELEASE\spring-web-5.1.8.RELEASE.jar;D:\repository\org\springframework\spring-beans\5.1.8.RELEASE\spring-beans-5.1.8.RELEASE.jar;D:\repository\org\springframework\spring-webmvc\5.1.8.RELEASE\spring-webmvc-5.1.8.RELEASE.jar;D:\repository\org\springframework\spring-aop\5.1.8.RELEASE\spring-aop-5.1.8.RELEASE.jar;D:\repository\org\springframework\spring-context\5.1.8.RELEASE\spring-context-5.1.8.RELEASE.jar;D:\repository\org\springframework\spring-expression\5.1.8.RELEASE\spring-expression-5.1.8.RELEASE.jar" cn.waggag.Application
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
2019-07-26 13:16:55.925 INFO 2364 --- [ main] cn.waggag.Application : Starting Application on waggag with PID 2364 (D:\WorkSpace\IntelliJIDEA\SpringBoot\SpringBoot_Demo\target\classes started by waggag in D:\WorkSpace\IntelliJIDEA\SpringBoot)
2019-07-26 13:16:55.929 INFO 2364 --- [ main] cn.waggag.Application : No active profile set, falling back to default profiles: default
//监听的端口
2019-07-26 13:16:57.002 INFO 2364 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-07-26 13:16:57.023 INFO 2364 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-07-26 13:16:57.024 INFO 2364 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-07-26 13:16:57.135 INFO 2364 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-07-26 13:16:57.136 INFO 2364 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1159 ms
2019-07-26 13:16:57.347 INFO 2364 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-07-26 13:16:57.512 INFO 2364 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-07-26 13:16:57.514 INFO 2364 --- [ main] cn.waggag.Application : Started Application in 1.937 seconds (JVM running for 3.519)
2019-07-26 13:17:03.692 INFO 2364 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
2019-07-26 13:17:03.692 INFO 2364 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
2019-07-26 13:17:03.697 INFO 2364 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 5 ms
三、Java配置
3.1、曾经数据库连接池配置
<!-- 配置连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
3.2、尝试使用Java配置
java配置主要靠java类和一些注解,比较常用的注解有:
- @Configuration:声明一个类作为配置类,代替xml文件
- @Bean:声明在方法上,将方法的返回值加入Bean容器,代替<bean>标签
- @value:属性注入
- @PropertySource:指定外部属性文件。
新建JdbcConfig类,配置数据库连接池:
package cn.waggag.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/**
* @description:
* @author: waggag
* @time: 2019/7/26 13:41
* @Company http://www.waggag.cn
*/
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
@Value("${jdbc.url}")
String url;
@Value("${jdbc.driverClassName}")
String driverClassName;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
解读:
- @Configuration:声明我们JdbcConfig是一个配置类
- @PropertySource:指定属性文件的路径是:classpath:jdbc.properties
- @Value为属性注入值
- @Bean将 dataSource()方法声明为一个注册Bean的方法,Spring会自动调用该方法,将方法的返回值加入Spring容器中
- 然后我们就可以在任意位置通过@Autowired注入DataSource了!
Controller中测试是否成功配置
package cn.waggag.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.sql.DataSource;
@Controller
public class DemoController {
//测试jdbc配置类
@Autowired
private DataSource dataSource;
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println(dataSource);
return "Hello SpringBoot!";
}
}
{
CreateTime:"2019-07-26 14:02:25",
ActiveCount:0,
PoolingCount:0,
CreateCount:0,
DestroyCount:0,
CloseCount:0,
ConnectCount:0,
Connections:[
]
}
四、SpringBoot的属性注入
不过属性注入使用的是@Value注解。这种方式虽然可行,但是不够强大,因为它只能注入基本类型值。
在SpringBoot中,提供了一种新的属性注入方式,支持各种java基本数据类型及复杂类型的注入。
4.1、修改jdbc.properties文件名为application.properties
4.2、引入lombok的依赖
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
4.3、配置JdbcProperties类
package cn.waggag.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @description: SpringBoot的属性注入
* @author: waggag
* @time: 2019/7/26 13:41
* @Company http://www.waggag.cn
*/
@ConfigurationProperties(prefix = "jdbc")
//编译时自动为属性加入常用方法
@Data
public class JdbcProperties {
String url;
String driverClassName;
String username;
String password;
}
SpringBoot属性注入的测试
package cn.waggag.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
/**
* @description: Java属性注入
* @author: waggag
* @time: 2019/7/26 13:41
* @Company http://www.waggag.cn
*/
@Configuration
@PropertySource("classpath:jdbc.properties")
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {
@Value("${jdbc.url}")
String url;
@Value("${jdbc.driverClassName}")
String driverClassName;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
/**
* Java属性注入
*/
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
/**
* SpringBoot属性注入
*/
@Bean
public DataSource springBootJdbcSource(JdbcProperties properties){
DruidDataSource springBootJdbcSource = new DruidDataSource();
springBootJdbcSource.setDriverClassName(properties.driverClassName);
springBootJdbcSource.setUrl(properties.url);
springBootJdbcSource.setUsername(properties.username);
springBootJdbcSource.setPassword(properties.password);
return springBootJdbcSource;
}
}
-
通过
@EnableConfigurationProperties(JdbcProperties.class)
来声明要使用JdbcProperties
这个类的对象 -
然后你可以通过以下方式注入JdbcProperties:
-
@Autowired注入
@Autowired private JdbcProperties prop;
-
构造函数注入
private JdbcProperties prop; public JdbcConfig(Jdbcproperties prop){ this.prop = prop; }
-
声明有@Bean的方法参数注入
@Bean public Datasource dataSource(JdbcProperties prop){ // ... }
-
4.4、Controller测试
package cn.waggag.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.sql.DataSource;
/**
* @description: Controller层,测试使用
* @author: waggag
* @time: 2019/7/26 13:09
* @Company http://www.waggag.cn
*/
@Controller
public class DemoController {
//测试jdbc配置类
@Autowired
private DataSource dataSource;
//测试SpringBoot的属性注入
@Autowired
private DataSource springBootJdbcSource;
@RequestMapping("/hello")
@ResponseBody
public String hello(){
System.out.println(dataSource);
System.out.println(springBootJdbcSource);
return "Hello SpringBoot!";
}
}
4.5、SpringBoot属性注入二
/**
* SpringBoot属性注入二
*/
@Bean
@ConfigurationProperties(prefix = "jdbc")
public DataSource springBoot2JdbcSource(){
return new DruidDataSource();
}
直接向返回的连接池注入需要的参数。参数定义在application.perporties中,推荐使用。
4.6、yaml配置文件
Spring Boot弱化配置的特性让属性配置文件的使用也更加便捷,它默认支持对application.properties或application.yml属性配置文件处理,即在application.properties或application.yaml文件中添加属性配置,可以使用@Value注解将属性值注入到beans中,或使用@ConfigurationProperties注解将属性值绑定到结构化的beans中。
//基本格式
jdbc:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springboot
username: waggag
password: 225514
五、自动配置原理
5.1、SpringBoot的启动特别的两点
我们发现特别的地方有两个:
-
注解:@SpringBootApplication
-
run方法:SpringApplication.run()
5.2、了解@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 {
}
这里重点的注解有3个:
-
@SpringBootConfiguration
-
@EnableAutoConfiguration
-
@ComponentScan
@SpringBootConfiguration
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
通过这段我们可以看出,在这个注解上面,又有一个@Configuration
注解。通过上面的注释阅读我们知道:这个注解的作用就是声明当前类是一个配置类,然后Spring会自动扫描到添加了@Configuration
的类,并且读取其中的配置信息。而@SpringBootConfiguration
是来声明当前类是SpringBoot应用的配置类,项目中只能有一个。所以一般我们无需自己添加。
@EnableAutoConfiguration
关于这个注解,官网上有一段说明:
The second class-level annotation is
@EnableAutoConfiguration
. This annotation tells Spring Boot to “guess” how you want to configure Spring, based on the jar dependencies that you have added. Sincespring-boot-starter-web
added Tomcat and Spring MVC, the auto-configuration assumes that you are developing a web application and sets up Spring accordingly.
简单翻译以下:
第二级的注解
@EnableAutoConfiguration
,告诉SpringBoot基于你所添加的依赖,去“猜测”你想要如何配置Spring。比如我们引入了spring-boot-starter-web
,而这个启动器中帮我们添加了tomcat
、SpringMVC
的依赖。此时自动配置就知道你是要开发一个web应用,所以就帮你完成了web及SpringMVC的默认配置了!
总结,SpringBoot内部对大量的第三方库或Spring内部库进行了默认配置,这些配置是否生效,取决于我们是否引入了对应库所需的依赖,如果有那么默认配置就会生效。所以,我们使用SpringBoot构建一个项目,只需要引入所需框架的依赖,配置就可以交给SpringBoot处理了。除非你不希望使用SpringBoot的默认配置,它也提供了自定义配置的入口。
@ComponentScan
配置组件扫描的指令。提供了类似与
<context:component-scan>
标签的作用:通过 basePackageClasses 或者basePackages属性来指定要扫描的包。如果没有指定这些属性,那么将从声明这个注解的类所在的包开始,扫描包及子包
而我们的@SpringBootApplication注解声明的类就是main函数所在的启动类,因此扫描的包是该类所在包及其子包。因此,一般启动类会放在一个比较前的包目录中。确保可以扫描到所有添加注解的包。
5.3、总结
SpringBoot为我们提供了默认配置,而默认配置生效的条件一般有两个:
-
你引入了相关依赖
-
你自己没有配置
1)启动器
所以,我们如果不想配置,只需要引入依赖即可,而依赖版本我们也不用操心,因为只要引入了SpringBoot提供的stater(启动器),就会自动管理依赖及版本了。因此,玩SpringBoot的第一件事情,就是找启动器,SpringBoot提供了大量的默认启动器。
2)全局配置
SpringBoot的默认配置,都会读取默认属性,而这些属性可以通过自定义application.properties
文件来进行覆盖。这样虽然使用的还是默认配置,但是配置中的值改成了自定义的。因此玩SpringBoot的第二件事情,就是通过application.properties
来覆性盖默认属值,形成自定义配置。我们需要知道SpringBoot的默认属性key,非常多。
demo地址:链接: https://share.weiyun.com/5YDSvim (密码:FC3c)