Annotation Interface JpaDataRoute
@Retention(RUNTIME)
@Target(TYPE)
@Documented
@Import({JpaSpringLiquibaseFactoryBeanRegistrar.class,JpaDataRouteEntityManagerFactoryBeanRegistrar.class,JpaDataRoutableDataSourceBeanRegistrar.class,JpaPackageDataRouteSupplierBeanRegistrar.class,JpaEmbeddedDataSourceFactoryBeanRegistrar.class,JpaPooledDataSourceFactoryBeanRegistrar.class,JpaTransactionManagerFactoryBeanRegistrar.class,JpaTransactionTemplateFactoryBeanRegistrar.class})
public @interface JpaDataRoute
Annotation used to describe points of configuration key to establishing a
RoutableDataSource
for subsequent inclusion in a RoutingJpaDataSource
defined
elsewhere. When combined with a DataRouteContext
thread local, a RoutingJpaDataSource can
select from one or more injected RoutableDataSource instances that match the routing key
described by DataRouteContext. This allows dynamic connection acquisition and transaction
behavior tied to a specific datasource and backing datastore.
Data route configuration is interesting in cases where it is desirable to run multiple
microservices in a single JVM/classloader. Such a configuration can be advantageous for
development usage, as well as optimized configuration for production. Not every situation
requires every service be deployed in a granular fashion, and infrastructure footprint can be
minimized in some cases by composing multiple services together into a single uber service.
Broadleaf resource tier services are designed to be composed in this way and data route
configuration plays a part in enabling that.
JpaDataRoute is usually described on a JPA specific autoconfiguration for a microservice. For
example,
There are a number of annotations mentioned here, all important in one way or another for achieving a microservice with full JPA data routing behavior.@ConditionalOnProperty(name = "broadleaf.database.provider", havingValue = "jpa")
@Configuration
@JpaEntityScan(basePackages = "com.broadleafcommerce.promotion.offer.provider.jpa.domain", routePackage = "com.broadleafcommerce.promotion.offer")
@EnableJpaRepositories(basePackageClasses = JpaOfferRepository.class, repositoryFactoryBeanClass = JpaTrackableRepositoryFactoryBean.class, entityManagerFactoryRef = "offerEntityManagerFactory", transactionManagerRef = "offerTransactionManager")
@EnableConfigurationProperties(OfferProperties.class)
@JpaDataRoute(boundPropertiesType = OfferProperties.class, routePackage = "com.broadleafcommerce.promotion.offer", routeKey = "offer", supportingRouteTypes = {NotificationStateDataRouteSupporting.class, LockDataRouteSupporting.class, ApplicationDataRouteSupporting.class, TranslationDataRouteSupporting.class})
public class OfferJpaAutoConfiguration {
@ConditionalOnProperty(name = "broadleaf.database.provider", havingValue = "jpa")
This conditional annotation gates this configuration on whether or not the currently configured
database provider is "jpa" (this is the default). Having such a condition allows for
autoconfiguration against multiple database providers (e.g. jpa and mongo) in the same codebase.
@JpaEntityScan(basePackages = "com.broadleafcommerce.promotion.offer.provider.jpa.domain",
routePackage = "com.broadleafcommerce.promotion.offer")
See JpaEntityScan
for more detail.
@EnableJpaRepositories(basePackageClasses = JpaOfferRepository.class,
repositoryFactoryBeanClass = JpaTrackableRepositoryFactoryBean.class,
entityManagerFactoryRef = "offerEntityManagerFactory",
transactionManagerRef = "offerTransactionManager")
This is the standard Trackable repository declaration, with the exception of explicit declaration
of the entity manager factory ref and the transaction manager ref. Note the "refs" here target
beans resulting from processing of the JpaDataRoute annotation against the routeKey()
.
Since the route is predetermined for these repositories, the specific RoutableDataSource
references can be defined here, rather than leaving the default configuration, which would cause
the components backed by the catch-all RoutingJpaDataSource
to be used. If the latter was
the case, additional DataRouteContext
support would need to be guaranteed, which would be
overkill for these repositories. The counterpoint to this is a repository defined in a common
library whose scope cross-cuts multiple microservice repositories. For example, the
CommonApplicationRepository defined in data tracking core is responsible for looking up
application related data in any supporting datasource. Such a repository should be backed by
RoutingJpaDataSource
so that it can service application related data lookup for any
context.
@EnableConfigurationProperties(OfferProperties.class)
See JpaPropertyRelated
for more detail.
@JpaDataRoute(boundPropertiesType = OfferProperties.class,
routePackage = "com.broadleafcommerce.promotion.offer", routeKey = "offer",
supportingRouteTypes = {NotificationStateDataRouteSupporting.class,
LockDataRouteSupporting.class, ApplicationDataRouteSupporting.class,
TranslationDataRouteSupporting.class})
This is the final configuration step for declaring the JPA route for a service. Note, based on
routeKey()
, a number of bean declarations are introduced, which can be overridden based
on expected bean ids. See JpaSpringLiquibaseFactoryBeanRegistrar
,
JpaDataRouteEntityManagerFactoryBeanRegistrar
,
JpaDataRoutableDataSourceBeanRegistrar
, JpaPackageDataRouteSupplierBeanRegistrar
,
JpaEmbeddedDataSourceFactoryBeanRegistrar
,
JpaPooledDataSourceFactoryBeanRegistrar
,
JpaTransactionManagerFactoryBeanRegistrar
,and
JpaTransactionTemplateFactoryBeanRegistrar
for more information on the beans resulting
from JpaDataRoute annotation usage.- Author:
- Jeff Fischer
-
Required Element Summary
Modifier and TypeRequired ElementDescriptionA short, unique key used to identify the resultingRoutableDataSource
in theRoutingJpaDataSource
via theDataRouteContext
.The portion of a package name that uniquely identifies this route. -
Optional Element Summary
Modifier and TypeOptional ElementDescriptionClass<? extends JpaPropertyRelated>
AJpaPropertyRelated
implementing class describing JPA, datasource, and liquibase configuration for the resultingRoutableDataSource
.Class<?>[]
Any cross-cutting repository concepts that should be supported by the resultingRoutableDataSource
.
-
Element Details
-
routePackage
String routePackageThe portion of a package name that uniquely identifies this route. For example, the Broadleaf offer service exposes a packagecom.broadleafcommerce.promotion.offer
that uniquely belongs to all classes in the offer service.- Returns:
- The portion of a package name that uniquely identifies this route.
-
routeKey
String routeKeyA short, unique key used to identify the resultingRoutableDataSource
in theRoutingJpaDataSource
via theDataRouteContext
. This key is also important in bean naming for the various bean registrars engaged by this annotation.- Returns:
- A short, unique key.
-
-
-
boundPropertiesType
Class<? extends JpaPropertyRelated> boundPropertiesTypeAJpaPropertyRelated
implementing class describing JPA, datasource, and liquibase configuration for the resultingRoutableDataSource
. This can be left with the default configuration when the default properties defined inJpaProperties
,DataSourceProperties
, andLiquibaseProperties
are desired. Such a case would be with aAutoConfigureTestDb
annotated test class - probably in a common library exposing data repositories.- Returns:
- A
JpaPropertyRelated
implementing class.
- Default:
- com.broadleafcommerce.common.jpa.data.DefaultDataRouteProperties.class
-
supportingRouteTypes
Class<?>[] supportingRouteTypesAny cross-cutting repository concepts that should be supported by the resultingRoutableDataSource
. For example, adding ApplicationDataRouteSupporting here will make sure that entities like JpaApplication from the data tracking library are registered with the entity manager factory for this route. SeeDataRouteSupporting
for more info. May be left with the default value if no cross-cutting repository concepts are supported in this route.- Returns:
- Any cross-cutting repository concepts that should be supported.
- Default:
- {com.broadleafcommerce.common.extension.data.DataRouteSupporting.class}
-