1.构建工具
1.1 依赖管理
每个Spring Boot发布版本都会提供一系列的依赖支持,包括所有会使用到的Spring模块及精简的三方依赖。开发者不需要关注依赖版本,只需按需引用即可,依赖都由Spring Boot管理。升级Spring Boot这些依赖也会一并升级。
自带的依赖清单通过spring-boot-dependencies提供,官方优先支持Maven和Gradle作为带有依赖管理功能的构建工具。
当然,如有必要开发者是可以覆盖具体的某些依赖的版本。
1.2 Starters
Starters是Spring Boot提供的一站式依赖描述集合,不需要手动拷贝与管理众多依赖描述。比如想使用Spring和JPA做数据库访问,只需在应用程序中引入spring-boot-starter-data-jpa依赖即可。
有了starters,应用程序的组建速度与依赖管理能力得到大幅提升。除了官方提供的starter之外,社区贡献的starter也很丰富。通过自动装配机制开发者可以完成自己的starter定制。
Spring Boot对Starters做了命名约束:
a.所有官方提供的starter的命名规则是spring-boot-starter-*,*代表具体的某一类型应用;
b.除官方提供外,所有其他(三方)starter的命名规则是thirdpartyproject-spring-boot-starter,应用名称作为前缀。
举几个官方提供的经典starter,都在org.springframework.boot路径下:
| Name | Description |
|---|---|
spring-boot-starter | Core starter, including auto-configuration support, logging and YAML |
spring-boot-starter-web | Starter for building web, including RESTful, applications using Spring MVC. Uses Tomcat as the default embedded container |
spring-boot-starter-amqp | Starter for using Spring AMQP and Rabbit MQ |
spring-boot-starter-aop | Starter for aspect-oriented programming with Spring AOP and AspectJ |
spring-boot-starter-artemis | Starter for JMS messaging using Apache Artemis |
spring-boot-starter-data-jpa | Starter for using Spring Data JPA with Hibernate |
spring-boot-starter-cache | Starter for using Spring Framework’s caching support |
2.代码结构
2.1 不建议使用缺省包
如果一个类没有声明在任何一个包下面也就是默认放在src/main/java目录下成为缺省包。虽然Java支持这样编译,但是Spring Boot不建议这么做,会使@ComponentScan, @ConfigurationPropertiesScan, @EntityScan或@SpringBootApplication逐个扫描class的注解出问题。
建议遵循Java包名约定,使用反转的领域名称组织包路径。 比如com.example.project。
2.2 主类Main
建议将主类Main放置代码工程根目录上,在所有其他类之上。
@SpringBootApplicaiont注解作用于主类上,它所在的包圈定了搜索其他特定部件的范围。比如一个JPA应用,Spring会扫描标记@SpringBootApplication的类所在的包下所有带有@Entity部件的类。
也可以使用@EnableAutoConfiguration和@ComponentScan代替@SpringBootApplication。
如下是一个经典代码组织结构:
com
+- example
+- myapplication
+- MyApplication.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
MyApplication类使用@SpringBootApplication标记,并声明主函数main:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
3.配置类
Spring Boot更倾向于基于Java的配置方式,尽管Spring Boot应用程序支持xml作为数据源启动,但使用@Configuration标记某个类作为主类更合适,通常是定义main函数的类。
不需要将所有@Configuration注解放入一个类中,可以使用@Import引入其他的配置类,@ComponentScan可以自动扫描包括@Configuration的所有Spring组件。
4.自动装配
Spring Boot的自动装配机制是对添加到classpath的jar依赖自动加载到Spring容器中。 比如添加了HSQLDB依赖,Spring Boot就会自动装配一个内存数据库,如果手动添加了自己的数据源,默认嵌入式数据库就会自动失效。
自动装配机制生效需要添加@SpringBootApplication或@EnableAutoConfiguration注解,官方建议直接在带有@Configuration的主类添加即可。
排除自动装配的类可以通过注解或配置项,比如@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })或spring.autoconfigure.exclude。
有一项需要注意的,尽管自动装配的类都是public的,但是唯一被认为是public API的是可作为禁用自动配置的类名。事实上,这些类的内部嵌套类及方法是为Spring Boot使用的,不建议开发者直接使用他们。
5.Spring Bean与DI
Spring Boot可以使用标准的Spring框架定义bean并注入他们需要的依赖,官方建议使用构造器注入依赖,使用@ComponentScan发现这些bean。
如果按照上文约定将主类在工程结构中置顶,Spring Boot会自动将带有@Component,@Service,@Repository,@Controller等注解的组件注册为Spring Bean。
比如,一个用@Service标记使用构造器注入RiskAccessor bean的Bean:
import org.springframework.stereotype.Service;
@Service
public class MyAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public MyAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
如果有不止一个构造器,就需要用@Autowired标记一个:
import java.io.PrintStream;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyAccountService implements AccountService {
private final RiskAssessor riskAssessor;
private final PrintStream out;
@Autowired
public MyAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
this.out = System.out;
}
public MyAccountService(RiskAssessor riskAssessor, PrintStream out) {
this.riskAssessor = riskAssessor;
this.out = out;
}
// ...
}
需要注意的是,使用构造器注入,需要将注入的私有对象riskAccessor标记为final,保证以后不可能被改变。
6.使用@SpringBootApplication注解
@SpringBootApplication注解等同于同时使用@EnableAutoConfiguration,@ComponentScan和@SpringBootConfiguration这三个注解。
他们分别用于激活Spring Boot自动装配机制,激活组件自动扫描,激活上下文中自定义的bean与引入的其他配置类的注册。
注意,这些特性都不是强制的,可以选择替换其中任一特性,比如不想使用自动组件扫描及注册自定义bean:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Import;
@SpringBootConfiguration(proxyBeanMethods = false)
@EnableAutoConfiguration
@Import({ SomeConfiguration.class, AnotherConfiguration.class })
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
MyApplication跟其他Spring Boot应用没有区别,除了以下几点:
a.无法自动扫描@Component注解的组件
b.无法自动装配@ConfigurationProperties注解的配置
c.开发者自定义的bean需要@Import显式引入
7.运行程序
将Spring Boot应用程序打包成jar并使用内嵌式Http服务器的好处是可以直接运行程序。
Spring Boot推荐将应用程序打包成jar而不是war。
如何加载一个Maven工程就不仔细讲了,这取决于所用的IDE。不过就Java而言,IDEA仍然是当下不二选择,即使是免费的IDEA Community依然可以满足日常开发工作。
运行程序,可以在IDE中debug运行,也可以打包为jar后通过java -jar运行,也可以借助构建工具运行,比如使用Maven就执行命令mvn spring-boot:run。
程序更新与重启也有被提及,因为Spring Boot是纯Java应用也应做到开箱即用,但是JVM热交换受限于可替换的字节码,更完整的解决方案可以参考JRebel。
8.开发工具
Spring Boot提供了专门用于开发阶段的工具,通过引入spring-boot-devtools依赖实现,包括热部署、自动重启、远程启动、全局开发工具配置等。