文章目录
原理简介
随着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时会报错。