diff --git a/using_spring_boot.md b/using_spring_boot.md index 4f669dc..e4dd83f 100644 --- a/using_spring_boot.md +++ b/using_spring_boot.md @@ -184,19 +184,203 @@ Starter POMs是可以包含到应用中的一个方便的依赖关系描述符 ### 组织你的代码 - - - - - - - - - - - - - +Spring Boot不需要使用任何特殊的代码结构,然而,这里有一些有用的最佳实践。 + +* 使用"default"包 + +当类没有包含`package`声明时,它被认为处于`default package`下。通常不推荐使用`default package`,并应该避免使用它。因为对于使用`@ComponentScan`,`@EntityScan`或`@SpringBootApplication`注解的Spring Boot应用来说,来自每个jar的类都会被读取,这会造成一定的问题。 + +**注**:我们建议你遵循Java推荐的包命名规范,使用一个反转的域名(例如`com.example.project`)。 + +* 定位main应用类 + +我们通常建议你将main应用类放在位于其他类上面的根包(root package)中。通常使用`@EnableAutoConfiguration`注解你的main类,并且暗地里为某些项定义了一个基础“search package”。例如,如果你正在编写一个JPA应用,被`@EnableAutoConfiguration`注解的类所在包将被用来搜索`@Entity`项。 + +使用根包允许你使用`@ComponentScan`注解而不需要定义一个`basePackage`属性。如果main类位于根包中,你也可以使用`@SpringBootApplication`注解。 + +下面是一个典型的结构: +```shell +com + +- example + +- myproject + +- Application.java + | + +- domain + | +- Customer.java + | +- CustomerRepository.java + | + +- service + | +- CustomerService.java + | + +- web + +- CustomerController.java +``` +`Application.java`文件将声明`main`方法,还有基本的`@Configuration`。 +```java +package com.example.myproject; + +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); + } + +} +``` +### 配置类 + +Spring Boot提倡基于Java的配置。尽管你可以使用一个XML源来调用`SpringApplication.run()`,我们通常建议你使用`@Configuration`类作为主要源。一般定义`main`方法的类也是主要`@Configuration`的一个很好候选。 + +**注**:很多使用XML配置的Spring配置示例已经被发布到网络上。你应该总是尽可能的使用基于Java的配置。搜索查看`enable*`注解就是一个好的开端。 + +* 导入其他配置类 + +你不需要将所有的`@Configuration`放进一个单独的类。`@Import`注解可以用来导入其他配置类。另外,你也可以使用`@ComponentScan`注解自动收集所有的Spring组件,包括`@Configuration`类。 + +* 导入XML配置 + +如果你绝对需要使用基于XML的配置,我们建议你仍旧从一个`@Configuration`类开始。你可以使用附加的`@ImportResource`注解加载XML配置文件。 + +### 自动配置 + +Spring Boot自动配置(auto-configuration)尝试根据你添加的jar依赖自动配置你的Spring应用。例如,如果你的classpath下存在`HSQLDB`,并且你没有手动配置任何数据库连接beans,那么我们将自动配置一个内存型(in-memory)数据库。 + +你可以通过将`@EnableAutoConfiguration`或`@SpringBootApplication`注解添加到一个`@Configuration`类上来选择自动配置。 + +**注**:你只需要添加一个`@EnableAutoConfiguration`注解。我们建议你将它添加到主`@Configuration`类上。 + +* 逐步替换自动配置 + +自动配置是非侵占性的,任何时候你都可以定义自己的配置类来替换自动配置的特定部分。例如,如果你添加自己的`DataSource` bean,默认的内嵌数据库支持将不被考虑。 + +如果需要找出当前应用了哪些自动配置及应用的原因,你可以使用`--debug`开关启动应用。这将会记录一个自动配置的报告并输出到控制台。 + +* 禁用特定的自动配置 + +如果发现应用了你不想要的特定自动配置类,你可以使用`@EnableAutoConfiguration`注解的排除属性来禁用它们。 +```java +import org.springframework.boot.autoconfigure.*; +import org.springframework.boot.autoconfigure.jdbc.*; +import org.springframework.context.annotation.*; + +@Configuration +@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) +public class MyConfiguration { +} +``` + +### Spring Beans和依赖注入 + +你可以自由地使用任何标准的Spring框架技术去定义beans和它们注入的依赖。简单起见,我们经常使用`@ComponentScan`注解搜索beans,并结合`@Autowired`构造器注入。 + +如果使用上面建议的结构组织代码(将应用类放到根包下),你可以添加`@ComponentScan`注解而不需要任何参数。你的所有应用程序组件(`@Component`, `@Service`, `@Repository`, `@Controller`等)将被自动注册为Spring Beans。 + +下面是一个`@Service` Bean的示例,它使用构建器注入获取一个需要的`RiskAssessor` bean。 +```java +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; + } + + // ... +} +``` +**注**:注意如何使用构建器注入来允许`riskAssessor`字段被标记为`final`,这意味着`riskAssessor`后续是不能改变的。 + +### 使用@SpringBootApplication注解 + +很多Spring Boot开发者总是使用`@Configuration`,`@EnableAutoConfiguration`和`@ComponentScan`注解他们的main类。由于这些注解被如此频繁地一块使用(特别是你遵循以上[最佳实践](http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#using-boot-structuring-your-code)时),Spring Boot提供一个方便的`@SpringBootApplication`选择。 + +该`@SpringBootApplication`注解等价于以默认属性使用`@Configuration`,`@EnableAutoConfiguration`和`@ComponentScan`。 +```java +package com.example.myproject; + +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); + } + +} +``` +### 运行应用程序 + +将应用打包成jar并使用一个内嵌HTTP服务器的一个最大好处是,你可以像其他方式那样运行你的应用程序。调试Spring Boot应用也很简单;你不需要任何特殊IDE或扩展。 + +**注**:本章节只覆盖基于jar的打包,如果选择将应用打包成war文件,你最好参考一下服务器和IDE文档。 + +* 从IDE中运行 + +你可以从IDE中运行Spring Boot应用,就像一个简单的Java应用,但是,你首先需要导入项目。导入步骤跟你的IDE和构建系统有关。大多数IDEs能够直接导入Maven项目,例如Eclipse用户可以选择`File`菜单的`Import…​` --> `Existing Maven Projects`。 + +如果不能直接将项目导入IDE,你可以需要使用构建系统生成IDE元数据。Maven有针对[Eclipse](http://maven.apache.org/plugins/maven-eclipse-plugin/)和[IDEA](http://maven.apache.org/plugins/maven-idea-plugin/)的插件;Gradle为[各种IDEs](http://www.gradle.org/docs/current/userguide/ide_support.html)提供插件。 + +**注**:如果意外地运行一个web应用两次,你将看到一个"端口已在使用中"错误。为了确保任何存在的实例是关闭的,STS用户可以使用`Relaunch`按钮而不是`Run`按钮。 + +* 作为一个打包后的应用运行 + +如果使用Spring Boot Maven或Gradle插件创建一个可执行jar,你可以使用`java -jar`运行你的应用。例如: +```shell +$ java -jar target/myproject-0.0.1-SNAPSHOT.jar +``` +运行一个打包的程序并开启远程调试支持是可能的,这允许你将调试器附加到打包的应用程序上: +```shell +$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \ + -jar target/myproject-0.0.1-SNAPSHOT.jar +``` +* 使用Maven插件运行 + +Spring Boot Maven插件包含一个`run`目标,它可以用来快速编译和运行应用程序。应用程序以一种暴露的方式运行,由于即时"热"加载,你可以编辑资源。 +```shell +$ mvn spring-boot:run +``` +你可能想使用有用的操作系统环境变量: +```shell +$ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M -Djava.security.egd=file:/dev/./urandom +``` +("egd"设置是通过为Tomcat提供一个更快的会话keys熵源来加速Tomcat的。) + +* 使用Gradle插件运行 + +Spring Boot Gradle插件也包含一个`run`目标,它可以用来以暴露的方式运行你的应用程序。不管你什么时候导入`spring-boot-plugin`,`bootRun`任务总是被添加进去。 +```shell +$ gradle bootRun +``` +你可能想使用那些有用的操作系统环境变量: +```shell +$ export JAVA_OPTS=-Xmx1024m -XX:MaxPermSize=128M -Djava.security.egd=file:/dev/./urandom +``` +* 热交换 + +由于Spring Boot应用程序只是普通的Java应用,那JVM热交换(hot-swapping)应该能出色的工作。JVM热交换在它能替换的字节码上有些限制,更全面的解决方案可以使用[Spring Loaded](https://github.com/spring-projects/spring-loaded)项目或[JRebel](http://zeroturnaround.com/software/jrebel/)。 + +关于热交换可以参考[“How-to”](http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-hotswapping)章节。 + +### 打包用于生产的应用程序 + +可执行jars可用于生产部署。由于它们是自包含的,非常适合基于云的部署。关于其他“生产准备”的特性,比如健康监控,审计和指标REST,或JMX端点,可以考虑添加`spring-boot-actuator`。具体参考[Part V, “Spring Boot Actuator: Production-ready features”](http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#production-ready)。