
We’re about six weeks into spring (at least in the northern hemisphere). But as far as DBOS is concerned Spring is only just beginning!
Last week, we released DBOS Transact Java version 0.8. There’s some great new features like dynamic workflow schedules, DELAYED workflows and cross language interoperability. But my favorite new feature is the Spring Boot integration via the new Transact Spring Boot Starter package. This package eliminates almost all of the setup and configuration code that you would otherwise need to write by hand to use DBOS into your Java application. Furthermore, it leverages Spring’s Aspect Oriented Programming (AOP) framework to simplify the implementation of DBOS @Workflow methods on Spring Boot @Service classes.
What DBOS Setup Looks Like Without Spring Boot
First off, let’s look at how we set up and configure DBOS in a non Spring Boot application. If you look at the dbos-starter app, you’ll see configuration code like this at the top of main:

This code is doing several things to get DBOS ready to run. It creates a DBOSConfig instance from which it creates the DBOS instance. It creates the proxy we will use to invoke @Workflow methods. And it integrates with Javalin lifecycle events to manage the DBOS lifecycle.
Auto-Config DBOS with Spring Boot
Fortunately, I can’t show you the equivalent setup and configuration code from a DBOS Spring Boot app like the widget-store demo app because there isn’t any! The DBOS instance bean? Constructed automatically via auto-configuration. The DBOSConfig used to create the DBOS instance? Auto-configured by reading external application property files. Lifecycle integration? You guessed it, auto-configured via- an auto-configured Lifecycle bean that integrates the DBOS’s lifecycle into Spring Boot’s lifecycle to be exact.
Of course, all of these auto-configured beans are just defaults. If you need to do something custom you can override those defaults in your application. For example, if you wanted to read configuration from a centrally managed directory service, you could provide your own DBOSConfig @Bean method while still using the auto-configured DBOS and Lifecycle beans. But if you’re not doing anything out of the ordinary, you shouldn’t need any DBOS configuration code at all. For example, the WidgetStoreConfig has a few things that make the app easier to demo (create the app database, run migrations, seed data, etc) but nothing DBOS related at all!
Using Spring AOP for Workflow Bookkeeping
The other major feature that we shipped in this first Transact Spring Boot Starter release is integration with Spring AOP. Durable execution is a classic example of a cross-cutting concern. We don’t want to add the durable execution bookkeeping DBOS does directly to @Workflow methods - that would lead to code duplication and create a maintenance nightmare. By separating out the bookkeeping code into the proxy, we’re able to isolate that code in a single location making it easy to reuse and maintain.
For “vanilla” Java applications, DBOS uses standard Java Dynamic Proxy Classes to implement @Workflow method bookkeeping. But Spring Boot Proxies have two important advantages over Dynamic Proxies. First, there is no need to manually create DBOS proxy objects. If you refer back to the dbos-starter code snipped previously, you’ll notice a call to “dbos.registerProxy”. Like the rest of DBOS configuration code, this is handled via an auto-configured component when using Spring Boot.
Second, you don’t have to define a separate interface and class when using Spring Boot proxies. If we again look at the dbos-starter app, you’ll see both the DurableStarterService interface and the DurableStarterServiceImpl class that implements the interface.

But in the widget store app, we do not need a separate interface. The checkoutWorkflow method of the WidgetStoreService class is directly annotated as a @Workflow - no interface needed! Like configuration and registration, handling @Workflow and @Step aspects are handled automatically by Transact Spring Boot Starter without the developer having to do anything beyond adding the @Service, @Workflow and @Step annotations.

Watch Out for "This"
You have to be careful when using “this” references with both DBOS and Spring Boot. All Java objects have an inherent “this” reference that points directly to the object itself, bypassing any proxies. If you invoke a @Workflow or @Step from inside your class via the “this” reference, DBOS isn’t given the opportunity to perform the bookkeeping it needs to do to make your application reliable.

The “this” problem happens with both Spring Boot proxies and standard Java dynamic proxies. To solve this, the workflow class needs a copy of the proxy. However, that proxy can’t be created until after the workflow class has been constructed. Thus you see the pattern from earlier when we manually created DBOS proxies without Spring Boot.

It turns out proxy bypass is an issue for Spring Boot independent of DBOS. To solve this, we can leverage Spring Boot’s self injection solution for DBOS code as well.

With Spring Boot Dependency Injection, constructor parameters are automatically provided when the class is instantiated. By annotating the setSelf method as @Autowired, Spring Boot knows that this method needs to be called as part of object construction. Unfortunately, using @Autowired alone would lead to a circular dependency problem where we need a WidgetStoreService instance to create a WidgetStoreService instance. We can annotate with @Lazy to break that circular dependency.
What's Next in DBOS Java
This is only the beginning of our Spring Boot integration journey. In our next release, we are adding support for Transactional Steps. In DBOS TypeScript, we call this a “datasource”, but that term is already used in Java. A Transactional Step is a function that updates an application database and records the step result within a single transaction. Storing the step result in the application database eliminates a small failure window without the overhead of two phase transactions. We plan to leverage Spring Boot’s rich Transaction Management infrastructure to provide a declarative approach similar to the existing @Transactional annotation.
If you want to learn more about the new DBOS Transact Java release, check out the Java Programming Guide and the Spring Boot Integration tutorial in our documentation.





