spring boot 使用及最佳实践
一、Spring boot的使用
1. 使用maven进行构建
用户可以通过继承spring-boot-starter-parent来获取默认的依赖。
- 默认java1.8编译级别
- 默认UTF-8编码设置
- 默认的DependencyManagement,继承与spring-boot-dependencies pom文件,用于管理常用依赖及版本。后续使用添加maven依赖可以省略version信息。
- repackage 配置
- 资源文件过滤
- plugin信息配置(包括exec、shade等)
- application.properties,application.yml文件及profile环境文件(如application-dev.properties或者application-dev.yml等)过滤。
starter parent 继承,pom依赖:
<!-- Inherit defaults from Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.3.RELEASE</version> </parent>
后续添加starter依赖,可以使用新的版本号进行覆盖。也可以通过定义相应的属性,来覆盖相应依赖的版本信息。
<properties> <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version> </properties>
支持的版本信息可以通过spring-boot-dependencies pom文件来查看。
2. 不通过继承start-parent来使用
有些时候,通过继承starter-parent来使用spring boot并不合适,例如,项目有自定义的需要继承的pom。这种情况下就可以通过使用spring-boot-dependencies pom文件来使用默认依赖(不包括默认插件配置),如下:声明type为pom,scope为import
<dependencyManagement> <dependencies> <dependency> <!-- Import dependency management from Spring Boot --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
这种情况下,定义相应的属性配置,将不再能覆盖已有版本信息。如果需要,可以通过使用以下方式,以spring-data-releasetrain为例:
<dependencyManagement> <dependencies> <!-- Override Spring Data release train provided by Spring Boot --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-releasetrain</artifactId> <version>Fowler-SR2</version> <type>pom</type> <scope>import</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
3. Spring boot maven插件使用
Spring boot包含一个可以将工程打包成可执行jar的maven插件,可以通过如下方式进行添加:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
继承starter-parent情况下,只配置此插件即可使用。如果需要更改stater-parent中的默认配置属性,可以通过定义进行覆盖。
二、最佳实践
1. 代码结构:
避免使用默认包
如果创建的类没有声明包信息,则类会默认使用默认包,默认包使用在使用诸如@ComponentScan
, @EntityScan
, 及@SpringBootApplication
时可能会引发特殊问题。
官方建议遵循java既有的命名约定规则,使用反转域名的方式命名包。例如,com.example.project.
2. 应用主类位置:
通常我们建议将主类放置于根路径下,注解@SpringBootApplication
通常放置于主类上,并且作为么某些扫描的根路径。如JPA配置的Entity扫描等。
@SpringBootApplication
注解包含 @EnableAutoConfiguration
和 @ComponentScan
,可以单独配置,或者直接使用@SpringBootApplication
简化配置。
如下,基本工程结构:
com +- example +- myapplication +- Application.java | +- customer | +- Customer.java | +- CustomerController.java | +- CustomerService.java | +- CustomerRepository.java | +- order +- Order.java +- OrderController.java +- OrderService.java +- OrderRepository.java
包含main方法的主类定义如下:
package com.example.myapplication; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
3. 配置类@Configuration:
Spring boot倾向使用基于java配置类的配置方式,建议使用主类作为主要的配置位置@Configuration。
4. 引入额外的配置类:
不需要将所有的配置放到一个配置类中,可以通过使用@Import注解引入额外的配置类信息。当然@ComponentScan注解会扫描包含@Configuration注解的配置类。
5. 引入xml配置
如果存在不许使用xml配置的情况,则可以通过@ImportResource注解来进行加载。
6. 自动配置@EnableAutoConfiguration
Spring boot基于添加的相应的功能jar进行自动配置。例如,类路径中有HSQLDB jar包的情况下,如果没有主动定义相应的数据源连接bean,则spring boot会自动配置内存数据库。
自动配置需添加相应的@EnableAutoConfiguration或者@SpringBootApplication来启用。通常放置其一于主类即可。
7. 自动配置的覆盖:
自动配置是非侵入性的,可以通过定义相应的自定义配置类进行覆盖,如果需要知道工程目前使用了那些自动配置,可以通过在启动时添加—debug选项,来进行输出。
8. 禁用某些自动配置
如果发现输出的日中包含一些不需要应用的自动配置可以通过在注解@EnableAutoConfiguration上添加exclude附加选项来禁用,如下:
import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.jdbc.*; import org.springframework.context.annotation.*; @Configuration @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) public class MyConfiguration { }
如果相应的配置类不再类路径下,则可以使用excludeName属性进行全路径配置。
另外,也可以通过配置文件spring.autoconfigure.exclude属性进行配置。
9. Spring bean及依赖注入
使用@ComponentScan进行bean的扫描及使用@Autowired进行以来注入。
如果工程结构遵循了以上的建议结构,那么添加@ComponentScan于主类上,就会将所有的诸如@Component
, @Service
, @Repository
, @Controller
等注解的类注册为spring bean。
如下示例,使用构造器诸如的@Service注解的服务类:
package com.example.service; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class DatabaseAccountService implements AccountService { private final RiskAssessor riskAssessor; @Autowired public DatabaseAccountService(RiskAssessor riskAssessor) { this.riskAssessor = riskAssessor; } // ... }
如果只有一个构造函数,则@Autowired可以省略。
10. @SpringBootApplication:等价以下三个注解默认配置
- @EnableAutoConfiguration:自动配置
- @ComponentScan:自动组件扫描
- @Configuration:配置类注解
package com.example.myapplication; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
包含的注解并不是强制性的,可以自定义的使用相应的注解以使用相应的特性:
package com.example.myapplication; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; @Configuration @EnableAutoConfiguration @Import({ MyConfig.class, MyAnotherConfig.class }) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
如上,不使用自动扫描发现,及主动引入基于java的配置类。
11. 运行你的工程
可以将工程打包为一个可运行的jar,并使用内置的http服务器来运行。
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar
或者添加调试:
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myapplication-0.0.1-SNAPSHOT.jar
使用maven插件运行:
$ mvn spring-boot:run