Extension for transaction-outbox-core which integrates with Guice.
<dependency>
<groupId>com.gruelbox</groupId>
<artifactId>transactionoutbox-guice</artifactId>
<version>5.5.447</version>
</dependency>
implementation 'com.gruelbox:transactionoutbox-guice:5.5.447'
See transactionoutbox-core for more information.
To get a TransactionOutbox
for use throughout your application, add a Singleton
binding for your chosen transaction manager and then wire in GuiceInstantiator
as follows:
@Provides
@Singleton
TransactionOutbox transactionOutbox(Injector injector, TransactionManager transactionManager) {
return TransactionOutbox.builder()
.transactionManager(transactionManager)
.persistor(Persistor.forDialect(Dialect.MY_SQL_8))
.instantiator(GuiceInstantiator.builder().injector(injector).build())
.build();
}
@Inject private TransactionOutbox outbox;
void doSomething() {
// Obtains a MyService from the injector
outbox.schedule(MyService.class).doAThing(1, 2, 3);
}
Alternatively, you may prefer to hide the use of TransactionOutbox
and create injectable "remote" implementations of specific services. This is a stylistic choice, and is more a Guice thing than a TransactionOutbox
thing, but is presented here for illustration.
Create a suitable binding annotation to specify that you want to inject the remote version of a service:
@Target({ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@BindingAnnotation
public @interface Remote {}
Bind TransactionOutbox
as per the example above, and add two more bindings to expose the "real" and "remote" versions of the service:
@Provides
@Remote
@Singleton // Can help performance
MyService remote(TransactionOutbox outbox) {
return outbox.schedule(MyService.class);
}
@Provides
MyService local() {
return new MyService();
}
Now you can inject the remote implementation and use it to schedule work. The following is exactly equivalent to the usage example above, just using an injected remote:
@Inject
@Remote
private MyService myService;
void doSomething() {
myService.doAThing(1, 2, 3);
}