随着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环境 |
Java开发越来越笨重
优点
缺点
Spring Boot可以使用Maven和Gradle作为项目构建
部署形式可以是jar或war
JDK最低要求1.6
支持以Groovy语言开发
使用IDEA,可以很自动化的构建一个SpringBoot项目,但其本质上还是一个Maven项目
如果网络有问题的话,可以手动构建
<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.0modelVersion>
<groupId>org.zln.learning.spbootgroupId>
<artifactId>spboot-demo01artifactId>
<version>0.0.1-SNAPSHOTversion>
<packaging>jarpackaging>
<name>spboot-demo01name>
<description>Demo project for Spring Bootdescription>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.3.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
上面的pom,添加的依赖并不多,但是实际上依赖很多
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);
}
}
代码说明
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.
*
* 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指SpringBoot启动时候的默认图案
我们在resources下新建一个
banner.txt 文件
打开网址 http://patorjk.com/software/taag
输入我们需要的字符,将生成结果粘贴到 banner.txt 文件中即可
SpringApplication application = new SpringApplication(SpbootDemo01Application.class);
application.setBannerMode(Banner.Mode.OFF);
application.run(args);
Spring Boot
使用一个全局的配置文件,放在 src/main/resources目录或类路径的config下
名字叫做 application.properties或application.yml
全局配置文件的作用是对一些默认配置进行修改
基本的全局配置
server.port=9090
server.context-path=/helloworld
如果使用的是yml,则可以
server:
port: 9090
contextPath: /helloworld
名称 | 描述 |
---|---|
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,如:MyBatis
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.0version>
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
主配置文件中的参数,可以直接使用@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
<configuration debug="false" scan="true" scanPeriod="1 seconds">
<contextName>logbackcontextName>
<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%npattern>
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}.zipfileNamePattern>
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是Spring用来针对不同的环境提供平不同的配置支持的
全局Profile配置使用 application-{profile}.properties
通过在application.properties中设置spring.profiles.active=dev 来设置活动的Profile
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<mainClass>org.zln.ehcache.MainmainClass>
configuration>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
即是没有这段,默认打出来的jar也是可执行的
Spring Boot的自动配置,其原理是Spring 4出现的条件化Bean
三种方式查看当前项目已启用和未启用的自动配置
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项目的条件下 |
当类存在的时候,自动配置这个Bean,并可将Bean的属性在application.properties文件中进行配置
<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.0modelVersion>
<groupId>com.pzrgroupId>
<artifactId>spring-boot-starter-pzrhelloartifactId>
<version>0.0.1-SNAPSHOTversion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>1.5.1.RELEASEversion>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-autoconfigureartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
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