一、介绍:
1、背景:
spring项目配置文件非常繁琐,springboot通过自动化配置等方式来简化spring原有样板化的配置。除此之外,使用Spring boot ,可以轻松的创建独立运行的程序,非常容易构建独立的服务组件,是实现分布式架构、微服务架构利器。Spring boot简化了第三方包的引用,通过提供的starter,简化了依赖包的配置。
2、Spring boot的优点
(1)轻松创建独立的Spring应用程序。
(2)内嵌Tomcat、jetty等web容器,不需要部署WAR文件。
(3)提供一系列的“starter” 来简化的Maven配置;开箱即用,尽可能自动配置Spring。这里主要是结合很多注解来自动注入、获取bean。
3、环境要求:
通过构建简单的REST应用,可以了解spring boot的开发基本流程,验证其简单、易用特性。Spring Boot 2.0.0.BUILD-SNAPSHOT 要求 Java 8 和 Spring Framework 5.0.2以上,Maven 3.2 以上或者Gradle 4。
4、文档说明:
二、springboot四大组件
starter、 autoconfigure、CLI 以及actuator。
1、starter
在我们的Spring Boot项目种的POM文件中总会看到这两种依赖:spring-boot-starter-xxx
(官方提供的starter)和 xxx-spring-boot-starter(
非官方的starter),
其中xxx是我们想要依赖的组件或者jar包。
2、autoconfigure
autoconfigure在我们的开发中并不会被感知,因为它是存在与我们的starter中的。所以我们的每个starter都是依赖autoconfigure的。
3、CLI
Spring Boot CLI是一个命令行使用Spring Boot的客户端工具;主要功能有:运行groovy脚本、打包groovy文件到jar、初始化Spring Boot项目 。
4、actuator
actuator是Spring Boot的监控插件。
三、应用程序组成:
1、目录结构
(1)src/main/java:编写代码存放的目录;
(2)src/main/resources。资源文件存放目录。默认配置文件 application.properties
(3)src/test/java。测试代码存放目录。
2、POM文件基础依赖:
spring boot项目默认使用maven来构建,一个基础的springboot项目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>com.yuny</groupId>
<artifactId>demo1</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-demo1</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.1、spring-boot-starter-parent
spring boot parent 当做项目的 parent。这种方式可以比较容易的使用父项目中的starters的依赖。 当然也可以不用继承spring-boot-starter-parent为父亲,比如项目已经有了其他的parent,
<!--<dependency>-->
<!--<groupId>org.springframework.boot</groupId>-->
<!--<artifactId>spring-boot-dependencies</artifactId>-->
<!--<version>${spring-boot.version}</version>-->
<!--<type>pom</type>-->
<!--<scope>import</scope>-->
<!--</dependency>-->
2.2、spring-boot-starter-web
web依赖,全栈Web开发模块,会增加web容器、springweb、springmvc、jackson-databind等相关的依赖。包含嵌入式tomcat、Springmvc
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2.3、单元测试:
包含JUnit、Hamcrest、Mockito
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
3、启动类:
Spring boot的启动是基于main方法的,下面是一个基本的启动类demo
@SpringBootApplication
public class SpringBootDemo1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemo1Application.class, args);
}
}
其中,@SpringBootApplication 是一个组合注解,
主要包含@SpringbootConfiguration+@EnableAutoConfiguration+@ComponentScan 三个注解。
3.1、@SpringbootConfiguration:
声明定义Bean,嵌套了@Component组件。扫描路径下的Bean会自动被装载到spring上下文中,代替以前用xml配置的Bean。
(1)@SpringBootConfiguration源码是@Configuration,表示该类为主配置类,可用来装配bean;
(2)@Configuration的源码是@Component:说明Spring的配置类也是Spring的一个组件。
它是JavaConfig形式的基于Spring IOC容器的配置类使用的一种注解。SpringBoot本质上就是一个Spring应用,通过这个注解来加载IOC容器的配置。所以在启动类里面标注了@Configuration,意味着它也是一个IOC容器的配置类
3.2、@EnableAutoConfiguration:(重点)
作用:开启自动装配类。自动映射扫描路径下的Bean,通常根据类的路径和Bean的上下文,自动进行配置。@EnableAutoConfiguration里有两个重要注解:
(1)@AutoConfigurationPackage:自动配置包
作用:给Spring容器中导入一个Registrar注册器组件。和@ComponentScan一样,也是将主配置类所在的包及其子包里面的组件扫描到IOC容器中,但是区别是:
- @AutoConfigurationPackage扫描@Enitity、@MapperScan等第三方依赖的注解
- @ComponentScan只扫描@Controller/@Service/@Component/@Repository这些常见注解。所以这两个注解扫描的对象是不一样的。
(2)@Import(AutoConfigurationImportSelector.class)——核心注解
作用:通过import导入第三方提供的bean的配置类:AutoConfigurationImportSelector:给容器中导入组件。扫描所有jar包类路径下的META-INF/spring.factories文件,将扫描到的这些文件包装成properties对象,从properties中获取到EnableAutoConfiguration.class类名对应的值,将这些值添加到容器中,用这些类做自动配置功能。
其中spring.factories文件是一组组的key=value的形式,key=接口 value=接口实现类(多个,逗号隔开)
3.3、@ComponentScan:
扫描主配置类包的所有包下的类,相当于xml配置文件中的context:component-scan。eg:pojo中的User类。会自动扫描路径下的所有@Component标注的类,包括@Service、@Repository、@Controller。如
@SpringBootApplication(scanBasePackages = "com.xxx")//扫描com.xxx包下的相关Configuration文件、自动映射文件、组件文件
4、自动装配过程:
SpringBoot启动的时候通过@EnableAutoConfiguration注解找到META-INF/spring.factories文件中的所有自动配置类,并对其加载,这些自动配置类都是以AutoConfiguration结尾来命名的。它实际上就是一个JavaConfig形式的IOC容器配置类,通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,如server.port。详细流程:
4.1、通过各种注解实现了类与类之间的依赖关系,容器在启动的时候SpringApplication.run(),调用EnableAutoConfigurationImportSelector.class的selectImports方法
4.2、selectImports方法调用SpringFactoriesLoader.loadFactoryNames方法扫描jar包类路径下的META-INF/spring.factories文件下,获取BeanConfiguration列表
4.3、loadFactoryNames方法会读取spring.factories中EnableAutoConfiguration.class类名对应的值
4.4、根据这些类上的注解判断,若条件满足,则该配置类生效,将配置文件中自己设置的属性值配置到对应的配置类中,最后注入到IOC容器中实现自动配置
5、启动方法
启动springboot应用常见有这几种方法:
(1)通过main函数来启动spring boot程序;
(2)springboot插件启动;
(3)java -jar xxx.jar启动。
四、搭建springboot项目:
1、springboot可以在http://start.spring.io/网站上自动搭建,或者在idea中使用spring initializr自动生成。
2、手动搭建:
(1)创建maven工程,在自动生成的pom文件添加springboot依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.1.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
(2)在src/main/resources下新建配置文件application.properties
zt.name=宝宝
zt.age=20
#时间格式化
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#时区设置
spring.jackson.time-zone=Asia/Chongqing
(3)编写controller接口
package com.demo.controller;
import java.util.Date;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
@RequestMapping("/user")
public class User {
@Value(value="${zt.name}")
private String name;
@Value(value="${zt.age}")
private int age;
@RequestMapping("/user")
@ResponseBody
public String user(){
System.out.println("user");
Date date = new Date();
return name+" "+age+" "+date;
}
}
(4)编写入口Java类:注解启动类需要放在自定义的包下,不可以直接放在src/main/java下,否则会报错
** WARNING ** : Your ApplicationContext is unlikely to start due to a @ComponentScan of the default package.
2023-12-11 15:50:23.311 WARN 24152 --- [ main] ationConfigEmbeddedWebApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/D:/repo/org/springframework/boot/spring-boot-autoconfigure/1.5.9.RELEASE/spring-boot-autoconfigure-1.5.9.RELEASE.jar!/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration.class]; nested exception is java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration due to org/springframework/dao/DataAccessException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
2023-12-11 15:50:23.317 INFO 24152 --- [ main] utoConfigurationReportLoggingInitializer :
Error starting ApplicationContext. To display the auto-configuration report re-run your application with 'debug' enabled.
2023-12-11 15:50:23.325 ERROR 24152 --- [ main] o.s.boot.SpringApplication : Application startup failed
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to read candidate component class: URL [jar:file:/D:/repo/org/springframework/boot/spring-boot-autoconfigure/1.5.9.RELEASE/spring-boot-autoconfigure-1.5.9.RELEASE.jar!/org/springframework/boot/autoconfigure/jdbc/DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration.class]; nested exception is java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration due to org/springframework/dao/DataAccessException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:311) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:272) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:135) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:287) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:272) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:92) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at ShiroApplication.main(ShiroApplication.java:9) [classes/:na]
Caused by: java.lang.IllegalStateException: Could not evaluate condition on org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseConfiguration due to org/springframework/dao/DataAccessException not found. Make sure your own configuration does not rely on that class. This can also happen if you are @ComponentScanning a springframework package (e.g. if you put a @ComponentScan in the default package by mistake)
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:55) ~[spring-boot-autoconfigure-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:102) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:81) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:64) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isConditionMatch(ClassPathScanningCandidateComponentProvider.java:371) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.isCandidateComponent(ClassPathScanningCandidateComponentProvider.java:355) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
at org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider.findCandidateComponents(ClassPathScanningCandidateComponentProvider.java:288) ~[spring-context-4.3.13.RELEASE.jar:4.3.13.RELEASE]
... 19 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/dao/DataAccessException
at org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration$EmbeddedDatabaseCondition.getMatchOutcome(DataSourceAutoConfiguration.java:211) ~[spring-boot-autoconfigure-1.5.9.RELEASE.jar:1.5.9.RELEASE]
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[spring-boot-autoconfigure-1.5.9.RELEASE.jar:1.5.9.RELEASE]
... 25 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.dao.DataAccessException
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_131]
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_131]
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:335) ~[na:1.8.0_131]
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_131]
... 27 common frames omitted
package com.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
并运行这个类启动项目
访问http://localhost:8080/user/user: