feat: Convert common module XML Spring configs to Java @Configuration classes#7
Open
devin-ai-integration[bot] wants to merge 5 commits intodevelop-7.0.xfrom
Open
Conversation
…classes Convert all 10 XML Spring application context files in the common module to equivalent Java @configuration classes in the org.broadleafcommerce.common.config.javaconfig package: - CommonPersistenceConfiguration: EntityManagerFactory, TransactionManager, cache, PU management - CommonConfiguration: core beans, component scanning, email, resources, class transformers - CommonEntityConfiguration: prototype-scoped entity beans for EntityConfiguration - CommonMBeansConfiguration: JMX/MBean beans (disabled via 'mbeansdisabled' profile) - CommonServletConfiguration: servlet context component scanning - CommonWrapperConfiguration: REST API wrapper beans - CommonAdminConfiguration: admin root context (imports CommonConfiguration) - CommonAdminServletConfiguration: admin servlet context - CommonSiteConfiguration: site context with resource handlers - CommonSiteServletConfiguration: site servlet context All bean names are preserved exactly for backward compatibility. XML files are kept in place until all modules are migrated. The common module compiles successfully with mvn compile -DskipTests -pl common. Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
Author
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
Addresses Devin Review finding - the XML defines blStatisticsService with appName and adapter properties that were accidentally omitted from the Java config. Without this bean, the adapter field remains null and logging operations become no-ops. Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
…t isolation Add exclude filter for org.broadleafcommerce.common.config.javaconfig to CommonConfiguration's @componentscan. Without this, all @configuration classes in the javaconfig package (servlet, site, admin, entity configs) would be picked up by the root context scan, breaking Spring context isolation. The explicitly @imported configs (CommonPersistenceConfiguration, CommonWrapperConfiguration, CommonMBeansConfiguration) are unaffected since @import works independently of component scanning. Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
…hods JPAPropertiesPersistenceUnitPostProcessor, ORMConfigPersistenceUnitPostProcessor, and JCachePersistenceUnitPostProcessor were instantiated via new, bypassing Spring dependency injection. All three classes rely heavily on @value, @resource, @Autowired, and @PostConstruct. Define each as a separate @bean so Spring manages their lifecycle, then inject them into the list bean. Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
…argetModeMap SharedEntityManagerBean is a FactoryBean, so typing the parameter as SharedEntityManagerBean causes Spring to inject the FactoryBean itself rather than its product (the EntityManager proxy). The XML value-ref resolves through the FactoryBean automatically. Changed parameter types to EntityManager and PlatformTransactionManager to match what consumers like PersistenceServiceImpl expect when casting map values. Co-Authored-By: Arjun Mishra <arjunsaxmishra@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A Brief Overview
This is the first step in migrating Broadleaf's Spring XML configuration to Java
@Configurationclasses. Thecommonmodule is the foundation — all other modules depend on it — so it must be converted first.All 10 XML application context files in
commonnow have equivalent Java@Configurationclasses inorg.broadleafcommerce.common.config.javaconfig. The original XML files are kept in place and unchanged until all downstream modules are migrated.Add Labels:
Mapping of XML → Java config:
bl-common-applicationContext-persistence.xmlCommonPersistenceConfigurationbl-common-applicationContext.xmlCommonConfigurationbl-common-applicationContext-entity.xmlCommonEntityConfigurationbl-common-applicationContext-mbeans.xmlCommonMBeansConfigurationbl-common-applicationContext-servlet.xmlCommonServletConfigurationbl-common-applicationContext-wrapper.xmlCommonWrapperConfigurationblc-config/admin/framework/bl-common-admin-applicationContext.xmlCommonAdminConfigurationblc-config/admin/framework/bl-common-admin-applicationContext-servlet.xmlCommonAdminServletConfigurationblc-config/site/framework/bl-common-applicationContext.xmlCommonSiteConfigurationblc-config/site/framework/bl-common-applicationContext-servlet.xmlCommonSiteServletConfigurationVerification:
mvn compile -DskipTests -pl commonpasses with no errors.Updates since initial revision:
Added missing
blStatisticsServicebean toCommonMBeansConfiguration. The XML defined this bean withappNameandadaptersetter injection, but it was omitted in the initial commit. Without it,StatisticsServiceImpl.adapterremainsnullandactivateLogging()/disableLogging()become no-ops.Excluded
javaconfigpackage fromCommonConfiguration's@ComponentScan. Without this filter, all@Configurationclasses in thejavaconfigpackage (CommonServletConfiguration,CommonSiteConfiguration,CommonAdminConfiguration,CommonEntityConfiguration, etc.) were being picked up by the root context scan. This broke Spring context isolation — notably,CommonServletConfigurationre-scans the veryweb.controllerandweb.configpackages thatCommonConfigurationexplicitly excludes. The fix addsorg.broadleafcommerce.common.config.javaconfigto the exclude filters. Configs that should be loaded in the root context (CommonPersistenceConfiguration,CommonWrapperConfiguration) are already explicitly@Import-ed and unaffected.Defined
PersistenceUnitPostProcessors as Spring-managed@Beanmethods inCommonPersistenceConfiguration. Previously,JPAPropertiesPersistenceUnitPostProcessor,ORMConfigPersistenceUnitPostProcessor, andJCachePersistenceUnitPostProcessorwere instantiated vianewinside the list factory bean method, bypassing Spring dependency injection. All three classes rely heavily on@Value,@Resource,@Autowired, and@PostConstruct— none of which fire on plainnewinstances. Each is now a separate@Beanand injected into theblPersistenceUnitPostProcessorslist bean. Note: unlike the original XML inner<bean>elements (which are anonymous), these are now named top-level beans — this is a minor semantic difference but necessary to enable Spring lifecycle management.Fixed
FactoryBeanunwrapping inblDefaultTargetModeMap. TheprodEntityManagerparameter was typed asSharedEntityManagerBean(theFactoryBeanitself) instead ofEntityManager(the product it creates). This caused Spring to inject the rawFactoryBeanobject rather than theEntityManagerproxy it produces. Consumers likePersistenceServiceImpl.getEntityManager()(line 184) cast map values to(EntityManager), which would throwClassCastExceptionat runtime. Similarly,blTransactionManagerwas typed asLifecycleAwareJpaTransactionManager— changed toPlatformTransactionManagerto match what the XMLvalue-refresolves and what consumers expect. The XMLvalue-ref="prodEntityManager"transparently resolves through theFactoryBean; the Java config must use the product type to get the same behavior.Additional context — items for reviewer attention:
Dual registration risk: Both XML and Java configs now coexist. Consumers must take care to load one or the other — not both — in the same
ApplicationContext, or beans will be double-registered. There is no guard mechanism added in this PR; that coordination is deferred to the per-module migration PRs.FactoryBeanreturn types:CommonPersistenceConfiguration.blCacheManager()returns aMergeJCacheManagerFactoryBeanandCommonMBeansConfiguration.blJmxNamingBean()returns aJndiObjectFactoryBean. Downstream beans inject the resolved values asObjectthen convert viaString.valueOf(). This relies on Spring's automaticFactoryBean.getObject()unwrapping. Verify this matches the XML behavior where<bean class="JndiObjectFactoryBean">transparently exposes the looked-up JNDI string.Merge-bean collections: Several beans (
blMergedClassTransformers,blMergedCacheConfigLocations,blMergedPersistenceXmlLocations,blTargetModeMaps, etc.) useListFactoryBean/MapFactoryBean. Broadleaf's merge infrastructure patches these at runtime. Confirm the Java-config-produced collections integrate correctly withMergeXmlWebApplicationContext.Bean name fidelity: Entity beans in
CommonEntityConfigurationuse FQCN names (e.g.,org.broadleafcommerce.common.email.domain.EmailTracking). These must match XML exactly sinceEntityConfigurationresolves by name.blPropertyPlaceholderConfigureris defined as a static@BeaninCommonConfiguration,CommonAdminServletConfiguration, andCommonSiteServletConfiguration. This mirrors the XML where each context level (root vs. servlet) has its own configurer. No conflict expected as these load in separate Spring contexts, but worth verifying.blTxAdvicenot translated: The XML persistence config defines<tx:advice id="blTxAdvice">with method-level propagation rules (e.g.REQUIRES_NEWforfindNextId). This is covered by@EnableTransactionManagementfor@Transactional-annotated code, but the explicit per-method-name advice is not replicated. Verify downstream modules don't referenceblTxAdviceby name or rely on its pointcut binding.No runtime/integration testing was performed — only compilation. Bean wiring correctness is not validated until an integration test or application startup exercises these configs.
Human review checklist:
CommonEntityConfigurationagainst their XML sourceblStatisticsServicesetter signatures match XML property injection (appNameas String,adapterasStatisticsServiceLogAdapter)blTxAdviceby nameListFactoryBean/MapFactoryBeanbeans are compatible with Broadleaf's merge infrastructurejavaconfigpackage exclude filter inCommonConfigurationis sufficient — check that no downstream module's@ComponentScancould still pick up context-specific configs unintentionallyCommonEntityConfigurationis NOT loaded into the main context (it should only be consumed viaEntityConfiguration's separateGenericXmlApplicationContextor explicit@Import)PersistenceUnitPostProcessorbeans receive their injected dependencies correctly at runtime (especiallyJPAPropertiesPersistenceUnitPostProcessorwhich has 18@Valuefields and a@PostConstructmethod)blDefaultTargetModeMapentries contain actualEntityManagerproxy andPlatformTransactionManagerat runtime — not theSharedEntityManagerBeanFactoryBean wrapperblTransactionManagertyped asPlatformTransactionManagerin the map still resolves to theLifecycleAwareJpaTransactionManagerinstance (it should, since that class implementsPlatformTransactionManager)Link to Devin session: https://app.devin.ai/sessions/a94b82fd29a44c7892a89ecf8907a729
Requested by: @Colhodm