Announcement: You can find the guides for Commerce 7.5 and later on the new Elastic Path Documentation site. This Developer Center contains the guides for Commerce 6.13.0 through 7.4.1.Visit new site

This version of Elastic Path Commerce is no longer supported or maintained. To upgrade to the latest version, contact your Elastic Path representative.

Plug-in Architecture

Plug-in Architecture

Elastic Path Core Commerce uses a lightweight plug-in architecture based on Spring functionality. This architecture allows you to create plug-ins that work seamlessly with existing Core Commerce modules, without needing to make any changes to the core application code or configuration files.

The Spring contexts of Elastic Path applications use wildcards to include Spring configuration files from well-know classpath locations. There are two patterns:

The first pattern is for the plugins to be included from an extensions module. For example, the elastic-path-servlet.xml file in the ext-integration-webapp module contains:

<import resource="classpath*:META-INF/elasticpath/conf/spring/plugin.xml"/commerce-legacy/>
<import resource="classpath*:META-INF/conf/ep-core-plugin.xml"/commerce-legacy/>

The second pattern is for the extensions to be included from a commerce-engine module. For example the import-export-context.xml file in the ep-importexport module contains:

<import resource="classpath*:META-INF/conf/ep-core-plugin.xml"/commerce-legacy/>
<import resource="classpath*:META-INF/conf/ep-importexport-plugin.xml" />

These statements cause the application to examine all JARs on the classpath and automatically include any copies of these files.

There are three separate plugin conventions in these examples:

  1. <import resource="classpath*:META-INF/elasticpath/conf/spring/plugin.xml> is used to automatically import Spring configuration from any JAR on the classpath with a plugin.xml file in META-INF/conf/ep-core-plugin.xml. Modules that declare Spring configuration in this location must not rely on any specific order in which their plugin.xml file is processed. Examples of modules that use this convention are the ep-messaging-camel module, and most Accelerator Kit modules.
  2. <import resource="classpath*:META-INF/conf/ep-core-plugin.xml> is used to import the ext-core module's configuration into other extension modules. The import should always be done after the generic plugin.xml imports to allow overriding generic plugin.xml configuration in ext-core.
  3. <import resource="classpath*:META-INF/conf/ep-importexport-plugin.xml> is defined in ep-import-export to create an extension point that is implemented by ep-importexport-plugin.xml in the ext-importexport extension module.

Overriding Existing Bean Definitions

Replacing a Bean

To completely override an existing bean definition in your webapp extension, in your webapp JAR extension's plugin.xml, you define a new bean with the exact same bean id as the bean you are overriding.

For example, suppose you want to override the priceListLookupService bean in ep-core/src/main/resources/spring/service/service.xml:

<bean id="priceListLookupService" 
        class="com.elasticpath.common.pricing.service.impl.PriceListLookupServiceImpl">
    <property name="plStackLookupStrategy" ref="plaStackLookupStrategy"/commerce-legacy/>
</bean>

In the ext-core module's ep-core-plugin.xml file, you would add the following:

<import resource="classpath:spring/service/ext-service.xml"/commerce-legacy/>

Then you would create an ext-service.xml file in the ext-core/resources/spring/service directory with the bean override:

<bean id="priceListLookupService" 
        class="com.elasticpath.extensions.common.pricing.service.impl.ExtPriceListLookupServiceImpl">
    <property name="plStackLookupStrategy" ref="plaStackLookupStrategy"/commerce-legacy/>
</bean>

Extending an existing bean

However, you may want to change only the configuration parameters of an existing bean definition, or override just the implementation class. There is a way to so this without replacing the entire bean definition. To do this, you need to use the PluginBeanFactoryPostProcessor.

The com.elasticpath.commons.util.impl.PluginBeanFactoryPostProcessor class is an implementation of the Spring BeanFactoryPostProcessor interface. Spring invokes this after all of the configuration has been discovered and loaded in memory, but before the actual objects are created.

Below is a PluginBeanFactoryPostProcessor bean definition:

<bean class="com.elasticpath.commons.util.impl.PluginBeanFactoryPostProcessor">
  <property name="extensionBeanName" value="EXTENSION_BEAN_NAME"/commerce-legacy/>
  <property name="extensionClassName" value="EXTENSION_CLASS_NAME"/commerce-legacy/>
  <property name="propertyName" value="PROPERTY_NAME"/commerce-legacy/>
  <property name="propertyValue" ref="PROPERTY_VALUE"/commerce-legacy/>
</bean>

To override or extend an existing built-in bean, add a PluginBeanFactoryPostProcessor bean definition in your extension Spring configuration and specify the following properties:

Property Description

extensionBeanName

The name of the bean you want to override.

extensionClassName

The class to set the overridden bean to use. (This property can be omitted if you don't need to change the bean class that was assigned in the original bean definition.)

propertyName

The name of the property to override or add. (This can be ommitted if you are not changing any properties)

propertyValue

The value you want to assign to the property.

For example, overriding the implementation class of priceListLookupService class could be done without copying any bean properties:

<bean class="com.elasticpath.commons.util.impl.PluginBeanFactoryPostProcessor">
    <property name="extensionBeanName" value="priceListLookupService"/commerce-legacy/>
    <property name="extensionClassName" value="com.elasticpath.extensions.common.pricing.service.impl.ExtPriceListLookupServiceImpl">
</bean>

Overriding multiple properties

To override multiple properties on a particular bean, use the propertiesMap property as follows:

<property name="propertiesMap">
    <map>
        <entry key="customerService" ref="customerService"/commerce-legacy/>
        <entry key="elasticPath" ref="elasticPath"/commerce-legacy/>
    </map>
</property>
Note:

Functionality can be added to this architecture by modifying the PluginBeanFactoryPostProcessor.postProcessBeanFactory() method implementation. For example, you could add an extendList property to allow a property value to add to a bean's list property rather than overwrite it.