Previously we used a dedicated BeanPostProcessor to decorate beans that expose transactional event listeners with an interceptor to mark event publications as completed if the method invocation completes successfully. We now have simplified the arrangement by using Spring's auto-proxy creation and registering an Advisor implementation. This allows us to properly and reliably order the interceptor between the async one (goes before ours) and the transactional one (goes after ours). Also, this significantly simplifies the implementation of the interceptor as we can assume only commit listener methods being intercepted in the first place.
The ApplicationListener we deploy to capture events published during a test method execution now uses an InheritableThreadLocal so that events published on threads spawned from the main test execution thread also end up in the PublishedEvents instance prepared for the test method.
Also, the registration of that particular event listener avoids duplicate registrations by inspecting the application context in use for the test method execution for an already registered listener, falling back to registering one.
Upgraded to Spring Boot 3.0.1. Added starters for web and added configuration to expose applicationmodules actuator. Tweak logs to follow Boot's default configuration. Removed obsolete milestone repository.
ModulithMetadata refers to SpringBootApplication in its Javadoc, which requires us to have the JAR on the classpath for Javadoc creation as the linting otherwise fails.
The configuration classes declaring SpringBootApplicationRuntime and ApplicationModulesRuntime beans now describe them as infrastructure beans so that they do not get reported as eagly initialized as their initialization will be triggered when creating the BeanPostProcessors our observability support is based on.
The configuration of the observability support now consistently refer to ApplicationModulesRuntime directly and to the Tracer instance via a supplier as the latter is only needed during the actual component invocation while the former is already needed to decide whether to decorate the instances in the first place. Simplify the inheritance arrangement underneath ModuleTracingSupport.
The logging adapter for ApplicationModuleInitializers now properly unwraps proxy types so that the log output uses the user classes properly.
Application modules can now declare instances of ApplicationModuleInititalizer to execute code upon an ApplicationStartedEvent.
This is achieved by registering a corresponding ApplicationListener in SpringModulithRuntimeAutoConfiguration to invoke all instances of AMI sorted via the Comparator introduced in GH-102. To make sure that the invocation order follows topological order, the runtime module strongly depends on JGraphT.
We now optionally integrate with the JGraphT library to calculate the topological order of modules based on their dependency structure. That order is then exposed in ApplicationModules' iteration and via ….getComparator().
Renamed FormattableJavaClass to FormattableType and allow it to be created from a plain Class as well.
In case AssertJ is on the classpath, test cases using the PublishedEventsExtension (for example, implicitly activated via @ApplicationModuleTest) can get an AssertablePublishedEvents injected into the method. In contrast to the original PublishedEvents, that one acts as AssertProvider so that it can be used in assertThat(…).… expressions to verify application events published.
Polished API in PublishedEvents for a more consistent experience.
Introduce Spring Modulith Actuator module to expose the application module structure as Spring Boot actuator. This required a Spring Modulith Runtime module to be extracted from the Spring Modulith Observability one. The former now contains the auto-configured ApplicationRuntime and ApplicationModulesRuntime bean instances to be able to bootstrap a ApplicationModules asynchronously on application startup. The actuator module then contains a Spring Boot @Endpoint implementation consuming the ApplicationModules to render JSON describing the application module structure.
We now provide @ApplicationModuleIntegrationListener as shortcut for the combination of @Async @Transactional @TransactionalEventListener to provide a dedicated annotation for the recommended integration arrangement.
Moved TestUtils from spring-modulith-test to spring-modulith-integration-test as it's only used there and doesn't need to be exposed to user applications.