Architecture

For the core library’s design — DatabasePlatform, audit families, SqlCapturingStatementInspector, QueryPlanExplainer, and cross-cutting invariants — see the core architecture reference.

This page covers only the Spring-specific concerns of the integration module.

Design intent

database-audits-core carries no dependency-injection annotations by design, so it can be used in any context. database-audits-spring-boot-integration provides the one piece core deliberately omits: Spring wiring. The production surface is DatabaseAuditTestConfiguration, a @TestConfiguration(proxyBeanMethods = false), together with DatabaseAuditSuite. DatabaseAuditSuite is a plain factory that wires every core audit and its collaborators for one (DataSource, EntityManagerFactory) pair and exposes the paired *AuditAssertion`s and the `DatabaseAuditAssertions facade; DatabaseAuditTestConfiguration builds one suite from the context’s primary DataSource/EntityManagerFactory and, through an AuditAssertionRegistrar, registers its assertions as beans. An application with several datasources adds one @TestConfiguration per extra datasource that builds another suite from its `@Qualifier’d beans — see the Multiple datasources guide.

The shared-capturer invariant — Spring wiring

The runtime audits read SQL from a SqlCapturingStatementInspector. The same bean instance must be Hibernate’s StatementInspector and the instance injected into the runtime audit beans. DatabaseAuditTestConfiguration ensures this by creating the capturer as a @Bean and passing the bean object to Hibernate via a HibernatePropertiesCustomizer:

@Bean
HibernatePropertiesCustomizer sqlCaptureHibernatePropertiesCustomizer(
        SqlCapturingStatementInspector inspector) {
    return props -> props.put(JdbcSettings.STATEMENT_INSPECTOR, inspector);
}

Passing the class name (a String) instead of the bean object would cause Hibernate to instantiate a second capturer that it fills but the audits never read.

Keeping beans in sync with core

DatabaseAuditSuite calls every core audit and collaborator constructor directly; there is no component scan. When a core constructor signature changes, or an audit is added or removed, DatabaseAuditSuite (and, for a new audit, its *AuditAssertion) must change in lockstep — a compile failure against core is the intended signal. The AuditAssertionRegistrar then exposes the new assertion as a bean automatically, so no per-audit @Bean method is added to DatabaseAuditTestConfiguration — see Adding an Audit.