Spring Boot 有许多包含 Spring MVC 的启动器。注意,一些启动器包括对 Spring MVC 的依赖,而不是直接包含它。本节回答关于 Spring MVC 和 Spring Boot 的常见问题。
只要 Jackson2 在类路径上,Spring Boot 应用程序中的任何 Spring @RestController public class MyController { @RequestMapping("/thing") public MyThing thing() { return new MyThing(); } }
只要
如果在类路径上有 Jackson XML 扩展( <dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency> 你还可能希望对 Woodstox 添加依赖项。它比 JDK 提供的默认 StAX 实现更快,还添加了漂亮的打印支持和改进的名称空间处理。下面的列表显示了如何包含 Woodstox 上的依赖项: <dependency> <groupId>org.codehaus.woodstox</groupId> <artifactId>woodstox-core-asl</artifactId> </dependency>
如果 Jackson 的 XML 扩展不可用,则使用 JAXB(在 JDK 中默认提供),另外还需要将 @XmlRootElement public class MyThing { private String name; // .. getters and setters }
要使服务器呈现 XML 而不是 JSON,你可能需要发送
Spring MVC(客户端和服务器端)使用
Spring Boot 还具有一些特性,可以更容易定制这种行为。
可以使用环境配置
例如,为了启用漂亮的打印,设置
这种基于环境的配置应用于自动配置的
上下文的
任何类型为
如果希望完全替换默认的
如果提供任何
更多详细信息请参阅 “小节 77.4, “自定义 @ResponseBody 渲染”” 部分和
Spring 使用
与常规 MVC 使用中一样,你提供的任何
更多详细信息请参阅
Spring Boot 包含 Servlet 3
当你希望在 Spring MVC 控制器处理程序方法中接收为
更多详细信息请参阅
Spring Boot 希望从应用程序的根(
要完全控制 MVC 配置,最简单的方法是为你自己的
有关的更多细节请参阅以下章节:
Spring Security 可以用于保护基于 Jersey 的 web 应用程序,其方式与用于保护基于 Spring MVC 的 web 应用程序的方式大致相同。但是,如果希望将 Spring Security 的方法级安全性用于 Jersey,则必须将 Jersey 配置为使用
必须在应用程序的 R @Component public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(Endpoint.class); setProperties(Collections.singletonMap( "jersey.config.server.response.setStatusOverSendError", true)); } } Spring Boot 提供了一些与 HTTP 客户端一起工作的启动器。本节回答有关使用它们的问题。
如 小节 33.1, “定制 RestTemplate” 中所述,可以使用
代理配置的确切细节取决于正在使用的底层客户端请求工厂。下面的示例使用 static class ProxyCustomizer implements RestTemplateCustomizer { @Override public void customize(RestTemplate restTemplate) { HttpHost proxy = new HttpHost("proxy.example.com"); HttpClient httpClient = HttpClientBuilder.create() .setRoutePlanner(new DefaultProxyRoutePlanner(proxy) { @Override public HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context) throws HttpException { if (target.getHostName().equals("192.168.0.5")) { return null; } return super.determineProxy(target, request, context); } }).build(); restTemplate.setRequestFactory( new HttpComponentsClientHttpRequestFactory(httpClient)); } }
Spring Boot 除了通常由 Spring Framework 的 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Spring Boot 有一个
如果对日志记录的唯一更改是设置各种日志记录器的级别,那么你可以在 logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR 还可以使用 "logging.file" 设置要写入日志的文件的位置(除了控制台)。
要配置日志系统的更细粒度设置,你需要使用
如果将 <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/base.xml"/> <logger name="org.springframework.web" level="DEBUG"/> </configuration>
如果你查看 spring-boot jar 中的
Spring Boot 还通过使用自定义 Logback 转换器在控制台(但不是在日志文件中)上提供了一些很好的 ANSI 彩色终端输出。有关的详细信息请参阅默认的
如果 Groovy 在类路径上,那么您你该能够用
如果希望禁用控制台日志记录并只将输出写入文件,则需要导入 <?xml version="1.0" encoding="UTF-8"?> <configuration> <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/> <include resource="org/springframework/boot/logging/logback/file-appender.xml" /> <root level="INFO"> <appender-ref ref="FILE" /> </root> </configuration>
你还需要将 logging.file=myapplication.log
Spring Boot 支持 Log4j 2 用于日志配置,如果它在类路径上。如果使用启动器来装配依赖项,则必须排除 Logback,然后再包含 log4j 2。如果不使用启动器,除了 Log4j 2 之外,还需要提供(至少) 最简单的路径可能是通过启动器,尽管它需要一些不规则的微调。下面的示例演示如何在 Maven 中设置启动器: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency> 下面的示例展示了在 Gradle 中设置启动器的一种方法: dependencies { compile 'org.springframework.boot:spring-boot-starter-web' compile 'org.springframework.boot:spring-boot-starter-log4j2' } configurations { all { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging' } }
除了默认的 XML 配置格式外,Log4j 2 还支持 YAML 和 JSON 配置文件。要配置 Log4j 2 以使用替代配置文件格式,请将适当的依赖项添加到类路径中,并将配置文件命名为与所选文件格式相匹配,如下例所示:
Spring Boot 包含多个启动数据源的启动器。本节回答与此相关的问题。
若要配置自己的 下面的示例演示如何在 bean 中定义数据源: @Bean @ConfigurationProperties(prefix="app.datasource") public DataSource dataSource() { return new FancyDataSource(); } 下面的示例演示如何通过设置属性自定义数据源: app.datasource.url=jdbc:h2:mem:mydb app.datasource.username=sa app.datasource.pool-size=30
假设你的
如果配置自定义 JNDI @Bean(destroyMethod="") @ConfigurationProperties(prefix="app.datasource") public DataSource dataSource() throws Exception { JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup(); return dataSourceLookup.getDataSource("java:comp/env/jdbc/YourDS"); }
Spring Boot 还提供了一个名为
下面的示例演示如何使用 @Bean @ConfigurationProperties("app.datasource") public DataSource dataSource() { return DataSourceBuilder.create().build(); }
要使用该 下面的示例演示如何通过设置属性自定义 JDBC 数据源: app.datasource.url=jdbc:mysql://localhost/test app.datasource.username=dbuser app.datasource.password=dbpass app.datasource.pool-size=30
然而,这有一个陷阱。因为连接池的实际类型没有公开,所以自定义 app.datasource.jdbc-url=jdbc:mysql://localhost/test app.datasource.username=dbuser app.datasource.password=dbpass app.datasource.maximum-pool-size=30
可以通过强制使用连接池并返回专用实现而不是
下面的示例演示如何用 @Bean @ConfigurationProperties("app.datasource") public HikariDataSource dataSource() { return DataSourceBuilder.create().type(HikariDataSource.class).build(); }
你甚至可以进一步利用 @Bean @Primary @ConfigurationProperties("app.datasource") public DataSourceProperties dataSourceProperties() { return new DataSourceProperties(); } @Bean @ConfigurationProperties("app.datasource") public HikariDataSource dataSource(DataSourceProperties properties) { return properties.initializeDataSourceBuilder().type(HikariDataSource.class) .build(); }
这个设置使你与 Spring Boot 默认为你所做的工作保持同步,只是选择了一个专用的连接池(在代码中),并且在相同的名称空间中公开了它的设置。因为 app.datasource.url=jdbc:mysql://localhost/test app.datasource.username=dbuser app.datasource.password=dbpass app.datasource.maximum-pool-size=30
更多详细信息请参阅 “Spring Boot features” 部分中的 “Section 29.1, “Configure a DataSource”” 和
如果需要配置多个数据源,可以应用前一节中描述的相同技巧。但是,你必须将一个
如果你创建了自己的 @Bean @Primary @ConfigurationProperties("app.datasource.first") public DataSourceProperties firstDataSourceProperties() { return new DataSourceProperties(); } @Bean @Primary @ConfigurationProperties("app.datasource.first") public DataSource firstDataSource() { return firstDataSourceProperties().initializeDataSourceBuilder().build(); } @Bean @ConfigurationProperties("app.datasource.second") public BasicDataSource secondDataSource() { return DataSourceBuilder.create().type(BasicDataSource.class).build(); }
两个数据源也绑定到高级定制。例如,可以将它们配置如下: app.datasource.first.type=com.zaxxer.hikari.HikariDataSource app.datasource.first.maximum-pool-size=30 app.datasource.second.url=jdbc:mysql://localhost/test app.datasource.second.username=dbuser app.datasource.second.password=dbpass app.datasource.second.max-total=30
你也可以将相同的概念应用到第二个 @Bean @Primary @ConfigurationProperties("app.datasource.first") public DataSourceProperties firstDataSourceProperties() { return new DataSourceProperties(); } @Bean @Primary @ConfigurationProperties("app.datasource.first") public DataSource firstDataSource() { return firstDataSourceProperties().initializeDataSourceBuilder().build(); } @Bean @ConfigurationProperties("app.datasource.second") public DataSourceProperties secondDataSourceProperties() { return new DataSourceProperties(); } @Bean @ConfigurationProperties("app.datasource.second") public DataSource secondDataSource() { return secondDataSourceProperties().initializeDataSourceBuilder().build(); } 前面的示例在自定义名称空间上配置两个数据源,其逻辑与 Spring Boot 在自动配置中使用的相同。
Spring Data 可以创建各种种类的
对于许多应用程序,你只需要在类路径上设置正确的 Spring Data 依赖项(JPA 的
Spring Boot 尝试根据所找到的 有关 Spring Data 的更多信息请参阅 Spring Data 项目页面。
Spring Boot 尝试根据它找到的 @Configuration @EnableAutoConfiguration @EntityScan(basePackageClasses=City.class) public class Application { //... } Spring Data JPA 已经提供了一些独立于供应商的配置选项(例如用于 SQL 日志记录的那些选项),Spring Boot 将这些选项以及 Hibernate 的一些其它选项公开为外部配置属性。其中一些是根据上下文自动检测的,因此不必设置它们。
还可以基于当前
在下面的示例中展示了最常见的设置选项: spring.jpa.hibernate.naming.physical-strategy=com.example.MyPhysicalNamingStrategy spring.jpa.show-sql=true
此外,在创建本地
Hibernate 使用两种不同的命名策略来将名称从对象模型映射到相应的数据库名称。物理和隐式策略实现的完全限定类名可以通过分别设置
默认情况下,Spring Boot 用
例如, 如果你喜欢使用 Hibernate 5 的默认值,请设置以下属性: spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl 或者,你可以配置以下 bean: @Bean public PhysicalNamingStrategy physicalNamingStrategy() { return new PhysicalNamingStrategyStandardImpl(); }
更多详细信息请参阅
要完全控制
即使默认的 // add two data sources configured as above @Bean public LocalContainerEntityManagerFactoryBean customerEntityManagerFactory( EntityManagerFactoryBuilder builder) { return builder .dataSource(customerDataSource()) .packages(Customer.class) .persistenceUnit("customers") .build(); } @Bean public LocalContainerEntityManagerFactoryBean orderEntityManagerFactory( EntityManagerFactoryBuilder builder) { return builder .dataSource(orderDataSource()) .packages(Order.class) .persistenceUnit("orders") .build(); }
上面的配置几乎是独立工作的。为了完成这个构想,你还需要为两个
如果使用 Spring Data,则需要相应地配置 @Configuration @EnableJpaRepositories(basePackageClasses = Customer.class, entityManagerFactoryRef = "customerEntityManagerFactory") public class CustomerConfiguration { ... } @Configuration @EnableJpaRepositories(basePackageClasses = Order.class, entityManagerFactoryRef = "orderEntityManagerFactory") public class OrderConfiguration { ... }
Spring Boot 默认情况下不会搜索或使用
默认的设置请参阅
Spring Data JPA 和 Spring Data Mongo 都可以自动为你创建存储库实现。如果它们都出现在类路径上,你可能需要做一些附加的配置来告诉 Spring Boot 要创建哪些存储库。最明确的方法是使用标准的 Spring Data
还可以使用标志( 对于其它自动配置的 Spring Data 存储库类型(Elasticsearch、Solr 和其它)也存在相同的障碍和相同的特性。要与它们一起工作,请相应地更改注解和标志的名称。
Spring Data REST 可以为你将
Spring Boot 暴露了一组定制
如果你想要配置 JPA 使用的组件,则需要确保组件在 JPA 之前初始化。当组件自动配置时,Spring Boot 会为你处理这个问题。例如,当 Flyway 是自动配置的,Hibernate 被配置为依赖于 Flyway,以便在 Hibernate 尝试使用它之前,Flyway 有机会初始化数据库。
如果你自己配置组件,则可以使用 /** * {@link EntityManagerFactoryDependsOnPostProcessor} that ensures that * {@link EntityManagerFactory} beans depend on the {@code elasticsearchClient} bean. */ @Configuration static class ElasticsearchJpaDependencyConfiguration extends EntityManagerFactoryDependsOnPostProcessor { ElasticsearchJpaDependencyConfiguration() { super("elasticsearchClient"); } }
如果你需要使用多个数据源的 jOOQ,你应该为每个数据源创建自己的
SQL 数据库可以根据你的堆栈的不同以不同的方式初始化。当然,如果数据库是一个单独的进程,你也可以手动进行。 JPA 具有 DDL 生成的特性,这些设置可以在数据库启动时运行。这是通过两个外部属性来控制的:
你可以显式地设置
此外,如果 Hibernate 从头开始创建该模式(即,如果
Spring Boot 可以自动创建
默认情况下,Spring Boot 启用 Spring JDBC 初始化器的故障快速特性。这意味着,如果脚本导致异常,则应用程序无法启动。可以通过设置
如果使用 Spring 批处理,它会用 SQL 初始化脚本对最流行的数据库平台进行预打包。Spring Boot 可以检测数据库类型并在启动时执行这些脚本。如果使用嵌入式数据库,默认情况下会发生这种情况。还可以为任何数据库类型启用它,如下面的示例所示: spring.batch.initialize-schema=always
还可以通过设置 Spring Boot 支持两种更高级的迁移工具:Flyway 和 Liquibase。
若要在启动时自动运行 Flyway 数据库迁移,请将
迁移是以 spring.flyway.locations=db/migration/{vendor}
前面的配置没有使用
从 flyway-core 中 的 Flyway 类可以看到可用的设置的细节,如模式和其他。此外,Spring Boot 提供了一小组属性(在
Flyway 支持 SQL 和 Java callbacks。若要使用基于 SQL 的回调,请将回调脚本放在
默认情况下, Flyway 在上下文中自动调用( 这有一个 Flyway 示例,你可以看到如何设置的东西。
你还可以使用 Flyway 为特定场景提供数据。例如,你可以将特定于测试的迁移放在 spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration
通过该设置,只有当
若要在启动时自动运行 Liquibase 数据库迁移,请将
默认情况下,从
默认情况下,Liquibase 在你的上下文中调用(
有关可用设置的详细信息,如上下文、默认模式 和 其它,请参阅 这有一个 Liquibase 示例,这样你就可以看到如何设置。 |