Spring boot-(2) Spring Boot使用
1. 构建系统
(1) 使用maven构建
1) 从Starter Parent继承
在项目中配置继承spring-boot-starter-parent,可以进行如下设置:
<!-- Inherit defaults from Spring Boot --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.BUILD-SNAPSHOT</version> </parent>
注意,设置版本号时,只需要在该parent中设置,如果想增加starters,则可以自动优化这些starters的版本信息。
在如上配置中,如果想覆盖独立的依赖,可以通过在项目中覆盖默认属性即可,如下所示:
<properties> <spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version> </properties>
2) 不使用parent的POM依赖
如果不使用spring-boot-starter-parent, 可以通过使用scope=import依赖,进而保留依赖管理的好处。如下所示:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.0.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
上述配置不允许使用property属性覆盖独立的依赖,如果想要实现覆盖,可以在项目中的dependencyManagement,作如下设置,且注意独立的依赖需要在spring-boot-dependencies之前。
<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> <scope>import</scope> <type>pom</type> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.0.0.BUILD-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
3) 使用Spring Boot Maven插件
Spring Boot包含Maven插件,能够将项目打包为可执行的jar包。可以在<plugins>中设置。如下所示:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
同样说明的是,如果使用parent依赖,则该插件不需要进一步配置。
(2) Starters
Spring Boot的Starters提供了Spring及其相关技术等方便的依赖描述,例如,如果需要使用Spring和JPA来访问数据库,可以在项目中增加spring-boot-starter-data-jpa依赖即可。目前支持的starters如下:
名称 | 说明 |
spring-boot-starter | 核心启动器,包括自动配置支持,日志记录和YAML |
spring-boot-starter-activemq | 使用Apache ActiveMQ的JMS启动器 |
spring-boot-starter-amqp | 使用Spring AMQP和Rabbit MQ的启动器 |
spring-boot-starter-aop | 使用Spring AOP和AspectJ进行面向切面编程的启动器 |
spring-boot-starter-artemis | 使用Apache Artemis的JMS启动器 |
spring-boot-starter-batch | 使用Spring Batch的启动器 |
spring-boot-starter-cache | 使用Spring Framework缓存支持的启动器 |
spring-boot-starter-cloud-connectors | 使用Spring Cloud连接器,简化了与Cloud Foundry和Heroku等云平台中的服务连接的启动器 |
spring-boot-starter-data-cassandra | 使用Cassandra分布式数据库和Spring Data Cassandra的启动器 |
spring-boot-starter-data-cassandra-reactive | 使用Cassandra分布式数据库和Spring Data Cassandra Reactive的启动器 |
spring-boot-starter-data-couchbase | 使用Couchbase面向文档的数据库和Spring Data Couchbase的启动器 |
spring-boot-starter-data-couchbase-reactive | 使用Couchbase面向文档的数据库和Spring Data Couchbase Reactive的启动器 |
spring-boot-starter-data-elasticsearch | 使用Elasticsearch搜索和分析引擎和Spring Data Elasticsearch的启动器 |
spring-boot-starter-data-jpa | 使用Spring数据JPA与Hibernate的启动器 |
spring-boot-starter-data-ldap | 使用Spring Data LDAP的启动器 |
spring-boot-starter-mongodb | 使用MongoDB面向文档的数据库和Spring Data MongoDB的启动器 |
spring-boot-starter-mongodb-reactive | 使用MongoDB面向文档的数据库和Spring Data MongoDB Recative的启动器 |
spring-boot-starter-neo4j | 使用Neo4j图数据库和Spring Data Neo4j的启动器 |
spring-boot-starter-redis | Redis key-value 数据存储与Spring Data Redis和Jedis客户端启动器 |
spring-boot-starter-redis-reactive | Redis key-value 数据存储与Spring Data Redis Reactive和Jedis客户端启动器 |
spring-boot-starter-data-rest | 通过使用Spring Data REST在REST上暴露Spring数据库的启动器 |
spring-boot-starter-data-solr | 使用Apache Solr搜索平台与Spring Data Solr的启动器 |
spring-boot-starter-freemarker | 使用FreeMarker视图构建MVC Web应用程序的启动器 |
spring-boot-starter-groovy-templates | 使用Groovy模板视图构建MVC Web应用程序的启动器 |
spring-boot-starter-hateoas | 使用Spring MVC和Spring HATEOAS构建基于超媒体的RESTful Web应用程序的启动器 |
spring-boot-starter-integration | Spring Integration 启动器 |
spring-boot-starter-jdbc | 使用JDBC与Tomcat JDBC连接池的启动器 |
spring-boot-starter-jersey | 使用JAX-RS和Jersey构建RESTful Web应用程序的启动器。spring-boot-starter-web的替代方案 |
spring-boot-starter-jooq | 使用jOOQ访问SQL数据库的启动器。 spring-boot-starter-data-jpa或spring-boot-starter-jdbc的替代方案 |
spring-boot-starter-json | 用于读取和写入json的启动器 |
spring-boot-starter-jta-atomikos | 使用Atomikos的JTA事务的启动器 |
spring-boot-starter-jta-bitronix | 使用Bitronix进行JTA 事务的启动器 |
spring-boot-starter-jta-narayana | Spring Boot Narayana JTA 启动器 |
spring-boot-starter-mail | Java Mail和Spring Framework的电子邮件发送支持的启动器 |
spring-boot-starter-mustache | 使用Mustache视图构建MVC Web应用程序的启动器 |
spring-boot-starter-quartz | Spring Boot Quartz启动器 |
spring-boot-starter-security | 使用Spring Security的启动器 |
spring-boot-starter-test | 使用JUnit,Hamcrest和Mockito的库测试Spring Boot应用程序的启动器 |
spring-boot-starter-thymeleaf | 使用Thymeleaf视图构建MVC Web应用程序的启动器 |
spring-boot-starter-validation | 使用Java Bean Validation 与Hibernate Validator的启动器 |
spring-boot-starter-web | 使用Spring MVC构建Web,包括RESTful应用程序。使用Tomcat作为默认的嵌入式容器的启动器 |
spring-boot-starter-web-services | Spring Web Services 启动器 |
spring-boot-starter-webflux |
Starter for building WebFlux applications using Spring Framework’s Reactive Web support |
spring-boot-starter-websocket | Starter for building WebSocket applications using Spring Framework’s WebSocket support |
spring-boot-starter-actuator | 使用Spring Boot Actuator提供生产准备功能,可帮助您监控和管理应用程序的启动器 |
spring-boot-starter-jetty | 使用Jetty作为嵌入式servlet容器的启动器。 spring-boot-starter-tomcat的替代方案 |
spring-boot-starter-log4j2 | 使用Log4j2进行日志记录的启动器。 spring-boot-start-logging的替代方法 |
spring-boot-starter-logging | 使用Logback进行日志记录的启动器。 默认的日志启动器 |
spring-boot-starter-reactor-netty | 使用Reactive Netty作为嵌入式reactive http服务器 |
spring-boot-starter-tomcat | 使用Tomcat作为嵌入式servlet容器的启动器。 spring-boot-starter-web的默认servlet容器启动器 |
spring-boot-starter-undertow | 使用Undertow作为嵌入式servlet容器的启动器。 spring-boot-starter-tomcat的替代方案 |
2. 构造代码
Spring Boot不需要任何任何特殊的代码组织,但有如下一些实践经验:
1) 不要使用"默认"的包
类中不包含"package"声明,即使用默认包。默认包尽量避免,在Spring Boot中使用@ComponentScan, @EntityScan或@SpringBootApplication注解时,会导致特殊异常。
2) 定位主应用类
通常建议将主应用类放在其他类之上根包中,@EnableAutoConfiguration注解经常会放在主类中。如下显示典型的层级:
com +- example +- myapplication +- Application.java | +- customer | +- Customer.java | +- CustomerController.java | +- CustomerService.java | +- CustomerRepository.java | +- order +- Order.java +- OrderController.java +- OrderService.java +- OrderRepository.java
Application.java中应该声明main方法,以及一些基础的@Configuration注解等,如下:
package com.example.myapplication; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
3. 配置类
Spring Boot通常建议配置时,主source是@Configuration类,通常,定义main方法的类也是作为主要的@Configuration一个很好的选择。
1) 导入额外的配置类
不需要将所有的@Configuration放在一个类中,@Import注解用于导入其他额外的配置类。另外,也可使用@CompomentScan注解自动选取所有的Spring组件,包含@Configutation类。
2) 导入XML配置
如果必须使用基于XML的配置,建议仍以@Configuration类开始,然后使用@ImportResource注解导入XML配置文件。
4. 自动配置
Spring Boot的自动配置会基于所添加的依赖包进行自动配置Spring应用。例如若HSQDB在classpath中,且没有手动配置任何数据库连接,Spring Boot会自动配置该内存数据库。
自动配置时,可以将@EnableAutoConfiguration或@SpringBootApplication增加到@Configuration类中。注意,应该只在主要的@Configuration类中增加一个@EnableAutoConfiguration注解。
1) 逐渐替代自动配置
自动配置是非侵入式的,你可以定义自己的配置来替代自动配置。如果想查看当前哪些自动配置在使用,可使用-debug开关启动应用程序,这将启动debug日志,并将自动配置日志记录到控制台。
2) 禁用指定的自动配置
如果你不想使用一些指定的自动配置类,可以使用@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 { }
如果类不在classpath中,可以使用excludeName属性指定全限定名。最后,也可以禁用自动配置类列表,通过使用spring.autoconfigure.exclude属性。
5. Spring Beans和依赖注入
可以随意使用标准Spring框架技术定义自己的beans及注入依赖。发现可以通过使用@ComponentScan注解来查找beans,使用@Autowired构造函数注入效果很好。
如果按照上述建议(将应用类放在根包中)构建代码,则可以增加@ComponentScan,且不需要任何参数。所有的应用组件如@Compent, @Service, @Reposity, @Controller等都将自动注册为Spring Beans。
下例展示了一个@Service Bean,通过构造函数注入获取一个RiskAssessor bean。
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; } }
如果一个bean只有一个构造函数,则可以省略@Autowired方法。注意如何使用构造方法注入使得riskAssessor标记为final, 后续使用该变量时则不可改变。
@Service public class DatabaseAccountService implements AccountService { private final RiskAssessor riskAssessor; public DatabaseAccountService(RiskAssessor riskAssessor) { this.riskAssessor = riskAssessor; } }
6. 使用@SpringBootApplication注解
许多Spring Boot开发者经常在主类中加入@Configuration, @EnableAutoConfiguration, @CompomentScan等注解, Spring Boot提供一个更简洁的选择@SpringBootApplication。如下所示:
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); } }
7. 运行程序
1) 运行jar包程序,可以使用如下命令:
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
2) 使用Maven插件,直接运行 mvn spring-boot:run,如果想使用MAVEN_OPTS环境参数,可以使用 export MAVEN_OPTS=-Xmx1024m
8. 开发工具
spring-boot-devtools模块可提供额外的开发时功能,可以通过如下方法加载该依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
(1) 属性默认值
缓存在生产中非常有益,但在开发过程中可能产生反效果。spring-boot-devtools将默认禁用缓存选项。缓存选项通常在application.properties中设置,而spring-boot-devtools模块不需要手动设置这些属性,而是自动应用更加合理的development-time配置。
(2) 自动重启
使用spring-boot-devtools的应用程序将在类路径上的文件发生更改时自动重启。且默认情况下,将监视指向文件夹的类路径上的任何条目。注意,静态资源和视图模板不需要重新启动应用程序。
Spring boot提供的重新启动技术使用两个类加载器。不会更改的类如第三方的jar被加载到基类加载器中。正在开发的类被加载到重新启动类加载器中。当应用程序重新启动时,重新启动类加载器将被丢弃,并创建一个新的类加载器。
1) 排除资源
在类路径下,某些资源更改时不一定需要触发重新启动。默认情况下,有一些排除项,如/META-INF/maven, /META-INF/resources, /resources/, /static, /public或/templates中的资源不会触发启动,但会重发实施重新加载。如果要自定义排除项,可以使用spring.devtools.restart.exclude属性。如要仅排除/static和/public,可以设置:spring.devtools.restart.exclude=static/**,public/**。如果要保留这些默认值并添加其他排除项,可使用spring-devtools.restart.additional-exclude属性。
2) 监视额外路径
有时需要监视不在类路径中的文件更改,进而重新启动或重新加载应用程序,可使用spring.devtools.restart.additional-paths属性配置其他路径。可以使用上述的spring.devtools.restart.exclude属性控制附加路径下的更改是否会触发完全重新启动或只是实施重新加载。
3) 禁用重启
如果不想使用重新启动功能,可以使用spring.devtools.restart.enabled属性来禁用。如需要完全禁用重新启动,在调用SpringApplication.run之前设置System属性。
public static void main(String[] args) { System.setProperty("spring.devtools.restart.enabled", "false"); SpringApplication.run(MyApp.class, args); }
4) 使用触发文件
如使用IDE编写代码或更改文件,你可能希望仅在特定时间触发重新启动,可以使用"触发文件"。可使用spring.devtools.restart.trigger-file属性。
5) 自定义重新启动类加载器
如上所述,IDE默认情况下打开的项目将使用"重新启动"类加载器加载,任何常规jar将使用基类加载器加载。若在多模块项目中工作,则可能需要自定义事件。为此,可以创建一个META-INF/spring-devtools.properties。spring-devtools.properties文件可以包含restart.exclude和restart.include.prefixed属性。如:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
(3) LiveReload
spring-boot-devtools包含一个嵌入式LiveReload服务器,可以在资源更改时用于触发浏览器更新。如果不想在应用程序中启动LiveReload服务器,可将spring.devtools.livereload.enabled属性设为false。
(4) 全局设置
可以向$HOME文件夹添加名为.spring-boot-devtools.properties的文件配置全局devtools设置(注意以"."开头)。添加到此文件的任何属性将适用于所在计算机上使用devtools的所有spring boot应用程序。例如:要配置重新启动以始终使用触发器文件,可以在~/.spring-boot-devtools.properties中添加:spring.devtools.reload.trigger-file=.reloadtrigger。
(5) 远程调用
spring boot不仅限于本地开发,也支持远程运行。远程支持是可选的,如果想使用该功能,首先需要确保devtools包含在重新打包存档中,如下所示:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
然后需要设置spring.devtools.remote.secret属性,如:spring.devtools.remote.secret=mysecret。注意:生产环境禁用远程调用。
远程devtools支持包含两部分:接收连接的服务端和运行在IDE上的客户端程序。当spring.devtools.remote.secret设置时,服务端部分自动可用。客户端部分则必须手动启动。