02 SpringBoot核心
文章目录
原理简介
随着JavaEE的不断壮大,Java的开发变得越来越复杂,这里的复杂,指的是写代码的方式。
配置文件一大堆,各种xml,properties。与其他项目进行整合集成的时候,也越来越不方便。
这个时候SpringBoot的出现,为解决上述问题提供了一个方案,可以说,是SpringBoot挽救了Java在服务端开发的陌路。
但是SpringBoot本身,是没有引入新技术的,其主要是基于Spring4中的条件注解特性,将原先需要编程人员手动操作的代码,统一集成到了内部,并且提供外部配置,同时兼顾了灵活性与简单性。
系统条件注解工具
条件注解 | 说明 |
---|---|
@ConditionalOnBean | 指定Bean是否存在 |
@ConditionalOnClass | 类路径下存在指定类 |
@ConditionalOnCloudPlatform | 是否是分布式平台 |
@ConditionalOnExpression | 由SpEL表达式决定 |
@ConditionalOnJava | JVM版本 |
@ConditionalOnJndi | 在JNDI存在的条件下查找指定的位置 |
@ConditionalOnMissingBean | 类路径缺失Bean的情况下 |
@ConditionalOnMissingClass | 类路径缺失Class的情况下 |
@ConditionalOnNotWebApplication | 非web环境 |
@ConditionalOnProperty | 指定属性是否有指定的值 |
@ConditionalOnResource | 类路径是否有指定的值 |
@ConditionalOnSingleCandidate | 指定Bean在容器中只有一个, 或者指定首选Bean |
@ConditionalOnWebApplication | 当前是web环境 |
概述
Spring Boot解决了什么问题
Java开发越来越笨重
- 配置多
- 部署复杂
- 第三方集成复杂
Spring Boot 核心功能
- Spring Boot可以以jar包的形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar 来运行
- Spring Boot可以选择内嵌Tomcat、Jetty、Undertow,无需以war包形式部署
- Spring Boot提供starter pom来简化Maven的依赖加载
- Spring Boot提供基于http、ssh、telnet对运行时项目的监控
- 无代码生成和xml配置
优缺点
优点
- 快速构建项目
- 对主流开发框架无缝集成
- 可独立运行项目,无需外部依赖Servlet容器
- 运行时应用监控
- 极大提高开发、部署效率
- 与云计算天然集成
缺点
- 学习资料少
- 如果Spring,特别是Spring4基础不扎实,对Spring Boot原理会弄不清
快速构建
Spring Boot可以使用Maven和Gradle作为项目构建
部署形式可以是jar或war
JDK最低要求1.6
支持以Groovy语言开发
使用IDEA,可以很自动化的构建一个SpringBoot项目,但其本质上还是一个Maven项目
如果网络有问题的话,可以手动构建
<?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>org.zln.learning.spboot</groupId> <artifactId>spboot-demo01</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spboot-demo01</name> <description>Demo project for Spring Boot</description> <!--Spring Boot项目必须添加这个父级依赖--> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.3.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </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> <!--添加starter和其他需要的依赖--> <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> <!--添加Spring Boot的编译插件--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
上面的pom,添加的依赖并不多,但是实际上依赖很多
- HelloWorld
package org.zln.learning.spboot; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @RestController public class SpbootDemo01Application { @RequestMapping("/") String index() { return "Hello Spring Boot"; } public static void main(String[] args) { SpringApplication.run(SpbootDemo01Application.class, args); } }
代码说明
- @SpringBootApplication
Spring Boot的核心注解,主要目的就是开启自动配置
SpringBoot基本配置
@SpringBootApplication
Spring Boot 通常有一个名为 *Application 的入口类,
入口类中的Main方法启动整个Spring Boot项目
@SpringBootApplication是SpringBoot的核心注解,从他的源码中可以看到,
它有一个@EnableAutoConfiguration注解;
@EnableAutoConfiguration让SpringBoot根据类路径中的jar,
为当前项目进行自动配置
如:添加了spring-boot-starter-web依赖,则自动添加Tomcat和Spring MVC的依赖,
然后Spring Boot会对Tomcat和SpringMVC进行自动配置
Spring Boot自动扫描与@SpringBootApplication所在的同级包及其下级包的Bean
建议入口类位置放在 groupId+arctifactId组合的包名下
@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 { /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude") Class<?>[] exclude() default {}; /** * Exclude specific auto-configuration class names such that they will never be * applied. * @return the class names to exclude * @since 1.3.0 */ @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName") String[] excludeName() default {}; /** * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses} * for a type-safe alternative to String-based package names. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackages") String[] scanBasePackages() default {}; /** * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to * scan for annotated components. The package of each class specified will be scanned. * <p> * Consider creating a special no-op marker class or interface in each package that * serves no purpose other than being referenced by this attribute. * @return base packages to scan * @since 1.3.0 */ @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses") Class<?>[] scanBasePackageClasses() default {}; }
关闭特定的自动注解
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
定制Banner
Banner指SpringBoot启动时候的默认图案
我们在resources下新建一个
banner.txt 文件
打开网址 http://patorjk.com/software/taag
输入我们需要的字符,将生成结果粘贴到 banner.txt 文件中即可
关闭 Banner
SpringApplication application = new SpringApplication(SpbootDemo01Application.class); application.setBannerMode(Banner.Mode.OFF); application.run(args);
Spring Boot 配置文件
Spring Boot
使用一个全局的配置文件,放在 src/main/resources目录或类路径的config下
名字叫做 application.properties或application.yml
全局配置文件的作用是对一些默认配置进行修改
基本的全局配置
server.port=9090 server.context-path=/helloworld
如果使用的是yml,则可以
server: port: 9090 contextPath: /helloworld
starter pom
- 官方
名称 | 描述 |
---|---|
spring-boot-starter | 这是Spring Boot的核心启动器,包含了自动配置、日志和YAML |
spring-boot-starter-actuator | 帮助监控和管理应用 |
spring-boot-starter-amqp | 通过spring-rabbit来支持AMQP协议(Advanced Message Queuing Protocol) |
spring-boot-starter-aop | 支持面向方面的编程即AOP,包括spring-aop和AspectJ |
spring-boot-starter-artemis | 通过Apache Artemis支持JMS的API(Java Message Service API) |
spring-boot-starter-batch | 支持Spring Batch,包括HSQLDB数据库。 |
spring-boot-starter-cache | 支持Spring的Cache抽象。 |
spring-boot-starter-cloud-connectors | 支持Spring Cloud Connectors,简化了在像Cloud Foundry或Heroku这样的云平台上连接服务。 |
spring-boot-starter-data-elasticsearch | 支持ElasticSearch搜索和分析引擎,包括spring-data-elasticsearch。 |
spring-boot-starter-data-gemfire | 支持GemFire分布式数据存储,包括spring-data-gemfire。 |
spring-boot-starter-data-jpa | 支持JPA(Java Persistence API),包括spring-data-jpa、spring-orm、Hibernate。 |
spring-boot-starter-data-mongodb | 支持MongoDB数据,包括spring-data-mongodb。 |
spring-boot-starter-data-rest | 通过spring-data-rest-webmvc,支持通过REST暴露Spring Data数据仓库。 |
spring-boot-starter-data-solr | 支持Apache Solr搜索平台,包括spring-data-solr。 |
spring-boot-starter-freemarker | 支持FreeMarker模板引擎。 |
spring-boot-starter-groovy-templates | 支持Groovy模板引擎。 |
spring-boot-starter-hateoas | 通过spring-hateoas支持基于HATEOAS的RESTful Web服务。 |
spring-boot-starter-hornetq | 通过HornetQ支持JMS。 |
spring-boot-starter-integration | 支持通用的spring-integration模块。 |
spring-boot-starter-jdbc | 支持JDBC数据库。 |
spring-boot-starter-jersey | 支持Jersey RESTful Web服务框架。 |
spring-boot-starter-jta-atomikos | 通过Atomikos支持JTA分布式事务处理。 |
spring-boot-starter-jta-bitronix | 通过Bitronix支持JTA分布式事务处理。 |
spring-boot-starter-mail | 支持javax.mail模块。 |
spring-boot-starter-mobile | 支持spring-mobile。 |
spring-boot-starter-mustache | 支持Mustache模板引擎。 |
spring-boot-starter-redis | 支持Redis键值存储数据库,包括spring-redis。 |
spring-boot-starter-security | 支持spring-security。 |
spring-boot-starter-social-facebook | 支持spring-social-facebook |
spring-boot-starter-social-linkedin | 支持pring-social-linkedin |
spring-boot-starter-social-twitter | 支持pring-social-twitter |
spring-boot-starter-test | 支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块。 |
spring-boot-starter-thymeleaf | 支持Thymeleaf模板引擎,包括与Spring的集成。 |
spring-boot-starter-velocity | 支持Velocity模板引擎。 |
spring-boot-starter-web | 支持全栈式Web开发,包括Tomcat和spring-webmvc。 |
spring-boot-starter-websocket | 支持WebSocket开发。 |
spring-boot-starter-ws | 支持Spring Web Services。 |
spring-boot-starter-actuator | 增加了面向产品上线相关的功能,比如测量和监控。 |
spring-boot-starter-remote-shell | 增加了远程ssh shell的支持。 |
spring-boot-starter-jetty | 引入了Jetty HTTP引擎(用于替换Tomcat)。 |
spring-boot-starter-log4j | 支持Log4J日志框架。 |
spring-boot-starter-logging | 引入了Spring Boot默认的日志框架Logback。 |
spring-boot-starter-tomcat | 引入了Spring Boot默认的HTTP引擎Tomcat。 |
spring-boot-starter-undertow | 引入了Undertow HTTP引擎(用于替换Tomcat)。 |
- 第三方starter pom
当我们需要某方面的技术的时候,先查查有没有对应的starter,如:MyBatis
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency>
Spring Boot
提倡无xml配置,但有时候必须用到xml配置,
使用
@ImportResource({"classpath:a.xml","classpath:b.xml"})导入即可
外部文件配置
SpringBoot允许使用
properties、
yaml文件或者命令行参数作为外部配置
命令行参数
#!/bin/sh nohup java -Xms128m -Xmx256m -jar train-basic-0.0.1-SNAPSHOT.jar --spring.profiles.active=A-prod >/dev/null 2>&1 &
--spring.profiles.active=A-prod就是指定了一个外部参数
application.yml中的配置
对于配置在
application.yml主配置文件中的参数,可以直接使用
@Value()注解进行获取
当然,使用
application.properties也是一样的
package org.zln.spb.demo01.web; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; /** * @Author 张柳宁 * @Description * @Date Create in 2018/1/31 * @Modified By: */ @RestController @Slf4j public class HelloController { @Value("${user.k1}") private String userK1; @RequestMapping("/hello") public String hello(){ log.info(userK1); return "Hello ,世界"; } }
application.yml内容为
user: k1: 张柳宁
类型安全的配置
如果不是
application配置文件,而是其他配置文件,那么就需要先指定
properties文件的位置
package com.tdk.train.config; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * Created by nbcoolkid on 2017-11-05. */ @Component @PropertySource(value = "classpath:db.properties",encoding = "utf-8") @ConfigurationProperties(prefix = "mysql") @Data public class DbConfBean { private String url; private String url2; private String username; private String username2; private String password; private String password2; }
将一个
properties配置文件与
JavaBean关联起来
日志配置
Spring Boot 支持Java UtilLogging、Log4J、Log4J2和LogBack作为日志框架
默认使用LogBack作为日志框架
# 配置日志文件路径 logging.file=logs/spboot-demo01.log #配置日志级别,格式:logging.level.包名=级别 logging.level.org.springframework.web=DEBUG
如果需要对日志进行详细的配置,则
logging: level: info config: classpath:logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false" scan="true" scanPeriod="1 seconds"> <contextName>logback</contextName> <property name="log.path" value="./logs/train-basic.log"/> <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${log.path}</file> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern> </rollingPolicy> <encoder> <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n </pattern> </encoder> </appender> <root level="info"> <appender-ref ref="console"/> <appender-ref ref="file"/> </root> </configuration>
Profile配置
Profile是Spring用来针对不同的环境提供平不同的配置支持的
全局Profile配置使用 application-{profile}.properties
通过在application.properties中设置spring.profiles.active=dev 来设置活动的Profile
SpringBoot打包出一个可执行jar
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <mainClass>org.zln.ehcache.Main</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
即是没有这段,默认打出来的jar也是可执行的
Spring Boot运行原理
Spring Boot的自动配置,其原理是Spring 4出现的条件化Bean
三种方式查看当前项目已启用和未启用的自动配置
- java -jar xx.jar --debug
- 全局配置文件:debug=true
- 运行的时候通过IDE为VM添加参数:-Ddebug
SpringBootApplication–>EnableAutoConfiguration
EnableAutoConfiguration–>Import
Import–>EnableAutoConfigurationImportSelector
EnableAutoConfigurationImportSelector–>AutoConfigurationImportSelector
扫描 META-INF/spring.factories 文件
spring-boot-autoconfigure-1.5.3.RELEASE.jar中就有
其中配置的任何一个自动注解配置类,都有条件注解
条件注解 | 说明 |
---|---|
@ConditionalOnBean | 当容器中存在指定Bean的条件下 |
@ConditionalOnClass | 当类路径下有指定类的情况下 |
@ConditionalOnExpression | 基于SpEL表达式作为判断条件 |
@ConditionalOnJava | 基于JVM版本作为判断条件 |
@ConditionalOnJndi | 在JNDI存在的条件下查找指定位置 |
@ConditionalOnMissingBean | 当容器中不存在指定Bean的条件下 |
@ConditionalOnMissingClass | 当类路径没有指定类的条件下 |
@ConditionalOnNotWebApplication | 当前项目不是Web项目的条件下 |
@ConditionalOnProperty | 指定属性是否有指定的值 |
@ConditionalOnResource | 类路径是否有指定的值 |
@ConditionalOnSingleCandidate | 当指定Bean在容器中只有一个, 或者虽然有多个但是指定首选的Bean |
@ConditionalOnWebApplication | 当前项目是Web项目的条件下 |
自定义 starter pom
当类存在的时候,自动配置这个Bean,并可将Bean的属性在application.properties文件中进行配置
- pom
<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.pzr</groupId> <artifactId>spring-boot-starter-pzrhello</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- 引用依赖的父包 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.1.RELEASE</version> </parent> <!-- 依赖包 --> <dependencies> <!-- spring boot 自动配置需要的包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency> <!-- spring boot需要的包 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
- 添加属性配置类
package com.pzr.spring_boot_stater_pzrhello; import org.springframework.boot.context.properties.ConfigurationProperties; /** * 属性配置类 * @author pzr * */ @ConfigurationProperties(prefix="hello") public class HelloServiceProperties { private static final String MSG = "world"; private String msg = MSG; public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; } }
代码说明:
使用@ConfigurationProperties注解来设置前缀,
在application.properties中通过hello.msg=来设置,若不设置,默认为hello.msg=world。
- 添加判断依据类
package com.pzr.spring_boot_stater_pzrhello; /** * 判断依据类 * @author pzr * */ public class HelloService { private String msg; public String sayHello(){ return "Hello "+msg; } public String getMsg() { return msg; } public void setMsg(String msg) { this.msg = msg; }; }
- 添加自动配置类
package com.pzr.spring_boot_stater_pzrhello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 自动配置类 * @author pzr * */ @Configuration @EnableConfigurationProperties(HelloServiceProperties.class) @ConditionalOnClass(HelloService.class) @ConditionalOnProperty(prefix="hello",value="enabled",matchIfMissing=true) public class HelloServiceAutoConfiguration { @Autowired private HelloServiceProperties helloServiceProperties; @Bean public HelloService helloService(){ HelloService helloService = new HelloService(); helloService.setMsg(helloServiceProperties.getMsg()); return helloService; } }
将HelloServiceAutoConfiguration配置到 src/main/resources/META-INF/spring.properties
org.springframework.boot.autoconfigure.EnableAutoConfiguration=
com.pzr.spring_boot_stater_pzrhello.HelloServiceAutoConfiguration
- @Configuration:使用该注解来说明该类是配置类,等价于xml中的beans
- @EnableConfigurationProperties(HelloServiceProperties.class):开启属性注入,对注解配置Bean的支持
- @ConditionalOnClass(HelloService.class):条件注解,当类路径下有指定的类的条件下。
- @ConditionalOnProperty(prefix=”hello”,value=”enabled”,matchIfMissing=true):条件注解,指定的属性是否有指定的值。当设置hello=enabled,如果没有设置则默认为true,即为条件符合。假如我们将matchIfMissing设置为false,则当设置hello=enabled时,条件为false,则不会将该Bean加载进容器类,当使用@Autowired注入HelloService时会报错。
- spring boot框架学习2-spring boot核心(1)
- Springboot核心注解笔记
- Spring Boot 2.0深度实践之核心技术篇(目前最新)
- 给你一份Spring Boot核心知识清单 推荐
- Spring Boot核心原理-自动配置
- 目录:SpringBoot 核心技术
- 牛班师兄系列之--Springboot核心原理
- springboot_02启动与扫描
- SpringBoot学习教程 - 02 - 配置DevTools,实现热部署
- SpringBoot-02热部署
- SpringBoot核心讲解
- spring boot框架学习3-spring boot核心(2)
- spring boot框架学习2-spring boot核心(1)
- Springboot的核心及相关配置
- spring-boot实战【02】:开发web应用
- Spring Boot 2.0深度实践之核心技术篇(三)--复习
- Spring Boot 的 10 个核心模块
- Spring Boot 2.0深度实践之核心技术篇
- 27-SpringBoot——核心-声明式事务
- Spring Boot核心配置