4.18。JTA的分布式事务
通过使用Atomikos
或Bitronix
嵌入式事务管理器,Spring Boot支持跨多个XA资源的分布式JTA事务。部署到合适的Java EE应用程序服务器时,还支持JTA事务。
当检测到JTA环境时,将使用Spring JtaTransactionManager
来管理事务。自动配置的JMS,DataSource和JPA Bean已升级为支持XA事务。您可以使用标准Spring习惯用法(例如@Transactional
)来参与分布式事务。如果您在JTA环境中,但仍要使用本地事务,则可以将spring.jta.enabled
属性设置为false禁用JTA自动配置。
4.18.1。使用Atomikos事务管理器
Atomikos是一种流行的开源事务管理器,可以嵌入到您的Spring Boot应用程序中。您可以使用spring-boot-starter-jta-atomikos
启动器来引入适当的Atomikos库。Spring Boot自动配置Atomikos,并确保将适当的depends-on
设置应用于您的Spring Bean,以正确的启动和关闭顺序。
默认情况下,Atomikos事务日志将写入应用程序主目录(应用程序jar文件所在的目录)中的transaction-logs
目录。您可以通过在application.properties文件中设置spring.jta.log-dir
属性来自定义此目录的位置。以spring.jta.atomikos.properties
开头的属性也可以用于自定义Atomikos UserTransactionServiceImp
。有关完整的详细信息,请参见AtomikosProperties
。
为了确保多个事务管理器可以安全地协调同一资源管理器,必须为每个Atomikos实例配置一个唯一的ID。默认情况下,此ID是运行Atomikos的计算机的IP地址。为确保生产中的唯一性,应为应用程序的每个实例的spring.jta.transaction-manager-id
属性配置一个不同的值。
4.18.2。使用Bitronix事务管理器
Bitronix是流行的开源JTA事务管理器实现。您可以使用spring-boot-starter-jta-bitronix
启动器将适当的Bitronix依赖项添加到项目中。与Atomikos一样,Spring Boot自动配置Bitronix并对您的bean进行后置处理,以确保启动和关闭顺序正确。
默认情况下,Bitronix事务日志文件(part1.btm和part2.btm)被写入应用程序主目录中的transaction-logs
目录。您可以通过设置spring.jta.log-dir
属性来自定义此目录的位置。以spring.jta.bitronix.properties
开头的属性也绑定到bitronix.tm.Configuration
Bean,从而可以进行完全自定义。有关详细信息,请参见Bitronix文档。
为了确保多个事务管理器可以安全地协调同一资源管理器,必须为每个Bitronix实例配置唯一的ID。默认情况下,此ID是运行Bitronix的计算机的IP地址。为确保生产中的唯一性,应为应用程序的每个实例的spring.jta.transaction-manager-id
属性配置一个不同的值。
4.18.3。使用Java EE托管事务管理器
如果将Spring Boot应用程序打包为war
或ear
文件,并将其部署到Java EE应用程序服务器,则可以使用应用程序服务器的内置事务管理器。Spring Boot尝试通过查看常见的JNDI位置(java:comp/UserTransaction
,java:comp/TransactionManager
等)来自动配置事务管理器。如果使用应用程序服务器提供的事务服务,通常还需要确保所有资源都由服务器管理并通过JNDI公开。Spring Boot尝试通过在JNDI路径(java:/JmsXA
或java:/XAConnectionFactory
)中查找ConnectionFactory来尝试自动配置JMS ,您可以使用spring.datasource.jndi-name
属性来配置DataSource
。
4.18.4。混合XA和非XA JMS Connections
使用JTA时,主要的JMS ConnectionFactory
Bean 是XA-aware,并参与分布式事务。在某些情况下,您可能想通过使用非XA ConnectionFactory处理某些JMS消息。例如,您的JMS处理逻辑可能需要比XA超时更长的时间。
如果要使用非XA ConnectionFactory,则可以注入nonXaJmsConnectionFactory
bean而不是@Primary
jmsConnectionFactory
bean。为了保持一致性,还使用别名为xaJmsConnectionFactory
的bean提供了jmsConnectionFactory
bean。
以下示例显示了如何注入ConnectionFactory实例:
// Inject the primary (XA aware) ConnectionFactory
@Autowired
private ConnectionFactory defaultConnectionFactory;
// Inject the XA aware ConnectionFactory (uses the alias and injects the same as above)
@Autowired
@Qualifier("xaJmsConnectionFactory")
private ConnectionFactory xaConnectionFactory;
// Inject the non-XA aware ConnectionFactory
@Autowired
@Qualifier("nonXaJmsConnectionFactory")
private ConnectionFactory nonXaConnectionFactory;
4.18.5。支持替代嵌入式事务管理器
XAConnectionFactoryWrapper
和XADataSourceWrapper
接口可用于支持替代嵌入式事务经理。这些接口负责包装XAConnectionFactory
和XADataSource
bean,并将它们作为常规ConnectionFactory
和DataSource
bean 公开,它们透明地注册到分布式事务中。DataSource和JMS自动配置使用JTA变体,前提是您拥有一个JtaTransactionManager
Bean并在ApplicationContext中注册了适当的XA包装器Bean 。
BitronixXAConnectionFactoryWrapper
和BitronixXADataSourceWrapper
提供了如何编写XA包装很好的例子。
4.19. Hazelcast
如果Hazelcast位于类路径上,并且找到了合适的配置,则Spring Boot会自动配置一个HazelcastInstance
,您可以在应用程序中注入使用。
如果定义一个com.hazelcast.config.Config
bean,Spring Boot会使用它。如果您的配置定义了一个实例名称,Spring Boot会尝试查找现有实例,而不是创建一个新实例。
您还可以指定通过配置使用的Hazelcast配置文件,如以下示例所示:
spring.hazelcast.config=classpath:config/my-hazelcast.xml
否则,Spring Boot会尝试从默认位置查找Hazelcast配置:在工作目录中或类路径的根目录中的hazelcast.xml
,或在相同位置的对应目录中的.yaml
。我们还检查是否设置了hazelcast.config
系统属性。有关更多详细信息,请参见Hazelcast文档。
如果类路径中存在hazelcast-client
,Spring Boot首先尝试通过检查以下配置选项来创建客户端:
com.hazelcast.client.config.ClientConfig
bean的存在。spring.hazelcast.config
属性定义的配置文件。hazelcast.client.config
系统属性的存在。- 在工作目录或在classpath的根目录中的
hazelcast-client.xml
。 - 在工作目录或在classpath的根目录中的
hazelcast-client.yaml
。
Spring Boot还具有对Hazelcast的显式缓存支持。如果启用了缓存,则会自动将HazelcastInstance
包装在CacheManager
实现中。
4.20. Quartz Scheduler
Spring Boot为使用Quartz Scheduler提供了许多便利,包括spring-boot-starter-quartz
启动器。如果Quartz
可用,则自动配置 Scheduler
(通过SchedulerFactoryBean
抽象)。
以下类型的Bean会被自动拾取并与Scheduler关联:
- JobDetail:定义特定的作业。
JobDetail
实例可以使用JobBuilder
API 构建 - Calendar
- Trigger:定义何时触发特定作业
默认情况下,使用内存JobStore
。但是,如果应用程序中有可用的DataSource
bean,并且spring.quartz.job-store-type
属性已相应配置,则可以配置基于JDBC的存储,如以下示例所示:
spring.quartz.job-store-type=jdbc
使用JDBC存储时,可以在启动时初始化模式,如以下示例所示:
spring.quartz.jdbc.initialize-schema=always
默认情况下,使用Quartz库自带的标准脚本检测并初始化数据库。这些脚本将删除现有表,并在每次重新启动时删除所有触发器。也可以通过设置spring.quartz.jdbc.schema
属性来提供自定义脚本。
要让Quartz使用应用程序的main DataSource之外的其他DataSource,请声明一个DataSource bean,并用@QuartzDataSource
注解其@Bean方法。这样做可确保SchedulerFactoryBean
和模式初始化都使用特定于Quartz的DataSource。
默认情况下,通过配置创建的作业将不会覆盖从持久性作业存储中读取的已注册作业。要启用覆盖现有作业定义的功能,请设置spring.quartz.overwrite-existing-jobs
属性。
可以使用spring.quartz
属性和SchedulerFactoryBeanCustomizer
bean 来定制Quartz Scheduler配置,从而允许以编程方式进行SchedulerFactoryBean
定制。可以使用spring.quartz.properties.*
来定制高级Quartz配置属性。
特别是,Executor
bean没有与调度程序相关联,因为Quartz通过spring.quartz.properties
提供了一种配置调度程序的方法。如果您需要自定义任务执行器,请考虑实现SchedulerFactoryBeanCustomizer
。
作业可以定义setter以注入数据映射属性。常规bean也可以类似的方式注入,如以下示例所示:
public class SampleJob extends QuartzJobBean {
private MyService myService;
private String name;
// Inject "MyService" bean
public void setMyService(MyService myService) { ... }
// Inject the "name" job data property
public void setName(String name) { ... }
@Override
protected void executeInternal(JobExecutionContext context)
throws JobExecutionException {
...
}
}
4.21。任务执行和计划
在上下文中没有Executor
bean的情况下,Spring Boot会使用合理的默认值自动配置 ThreadPoolTaskExecutor
,这些默认值可以自动与异步任务执行(@EnableAsync
)和Spring MVC异步请求处理相关联。
如果您在上下文中定义了一个自定义Executor,则常规任务执行(即@EnableAsync
)将透明地使用它,但由于需要AsyncTaskExecutor
实现(名为applicationTaskExecutor
),因此不会配置Spring MVC支持。根据你的目标的安排,你可以改变Executor到一个ThreadPoolTaskExecutor
或同时定义一个ThreadPoolTaskExecutor
和AsyncConfigurer
包装您的自定义Executor。
通过自动配置的TaskExecutorBuilder
,您可以轻松创建实例,以重现默认情况下自动配置的功能。
线程池使用8个核心线程,这些线程可以根据负载增长和收缩。可以使用spring.task.execution
名称空间对这些默认设置进行微调,如以下示例所示:
spring.task.execution.pool.max-size=16
spring.task.execution.pool.queue-capacity=100
spring.task.execution.pool.keep-alive=10s
这会将线程池更改为使用有界队列,以便在队列已满(100个任务)时,线程池最多增加到16个线程。池的收缩更加激进,因为当线程空闲10秒(而不是默认情况下的60秒)时,它们将被回收。
如果需要与计划的任务执行(@EnableScheduling
)关联,也可以自动配置 ThreadPoolTaskScheduler
。线程池默认使用一个线程,可以使用spring.task.scheduling
名称空间对这些设置进行微调。
如果要创建一个自定义的执行器或调度器,上下文提供了TaskExecutorBuilder
bean和TaskSchedulerBuilder
bean。
参考源码:
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
4.22。Spring Integration
Spring Boot为使用Spring Integration提供了许多便利,包括spring-boot-starter-integration
启动器。Spring Integration为消息传递以及其他传输(例如HTTP,TCP等)提供抽象。如果您的类路径上有Spring Integration,则可以通过@EnableIntegration
注释对其进行初始化。
Spring Boot还配置了一些功能,这些功能由其他Spring Integration模块的存在触发。如果spring-integration-jmx
也在类路径上,则消息处理统计信息将通过JMX发布。如果spring-integration-jdbc
可用,则可以在启动时创建默认的数据库架构,如以下行所示:
spring.integration.jdbc.initialize-schema=always
有关更多详细信息,请参见IntegrationAutoConfiguration
和IntegrationProperties
类。
默认情况下,如果存在Micrometer meterRegistry
bean,Spring Integration指标将由Micrometer管理。如果您希望使用旧版Spring Integration指标,请将DefaultMetricsFactory
Bean 添加到应用程序上下文中。
4.23。Spring Session
Spring Boot为各种数据存储提供了Spring Session自动配置。在构建Servlet Web应用程序时,可以自动配置以下存储:
- JDBC
- Redis
- Hazelcast
- MongoDB
构建反应式Web应用程序时,可以自动配置以下存储:
- Redis
- MongoDB
如果类路径上存在单个Spring Session模块,则Spring Boot会自动使用该存储实现。如果您有多个实现,则必须选择要用于存储会话的StoreType
实现。例如,要将JDBC用作后端存储,可以按以下方式配置应用程序:
spring.session.store-type=jdbc
您可以通过将store-type
设置为none
来禁用Spring Session 。
每种存储都有特定的附加设置。例如,可以为JDBC存储定制表的名称,如以下示例所示:
spring.session.jdbc.table-name=SESSIONS
要设置会话超时,您可以使用spring.session.timeout
属性。如果未设置该属性,则自动配置将回退到server.servlet.session.timeout
的值。
4.24。通过JMX进行监视和管理
Java管理扩展(Java Management Extensions,JMX)提供了监视和管理应用程序的标准机制。Spring Boot将最适合的MBeanServer
作为ID为mbeanServer
的bean 公开。您的任何bean 被标注有Spring JMX注释(@ManagedResource
,@ManagedAttribute
,或@ManagedOperation
)对它公开。
如果您的平台提供了标准MBeanServer
,则Spring Boot将使用该标准,并在必要时默认使用VM MBeanServer。如果全部失败,将创建一个新的MBeanServer。
有关更多详细信息,请参见JmxAutoConfiguration
。