Broadleaf Commerce 5.2.0-GA
Release date: July 7, 2017
Overview
The overall theme of the Broadleaf 5.2.0-GA release is largely around removing technical debt and supporting Spring Boot, and as a result is an architectural release to ensure future relevancy. Some of the efforts around supporting this goal were:
- Removal of the Broadleaf customized XML merge process
- First class support for Java-style Spring
@Configuration
classes - First class support for Spring Boot
- General supporting library updates and paying down technical debt
- Standardization around recent Spring improvements
New and Noteworthy
New Features
SEO Enhancements
New properties have been added to categories and products around specific <meta>
tags and canonical URLs. More information available in the feature documentation for meta titles and descriptions and canonical URLs.
GeoLocation API
We have a thin service layer around Geolocation with the ability to use resolved geolocation parameters to drive rule builders (e.g. offer codes, targeted content). Geolocation data is resolved using either Free GEO IP or Maxmind with the ability to plug in more. See the feature documentation for more information.
Framework and Architectural
Library Dependency Updates
Our minimum compatible versions have been brought up to date with the latest release versions for Spring and others:
- Spring core and Spring MVC: 4.1.9.RELEASE updated to 4.3.9.RELEASE
- Spring Security: 3.2.9.RELEASE updated to 4.2.3.RELEASE
- Jackson: 2.5.0 updated to 2.8.9
- Java servlet: 2.5. updated to 3.0.1
Native support for Spring Profiles
The ability to have different runtime property values in different environments has been available in Broadleaf since very early on. This capability was added in Spring 3.1, and the Broadleaf-specific environment specifier has been deprecated in favor of this pattern. This means that previously, the way to switch environments in Broadleaf and select different properties was a command line argument like this which is now deprecated:
-Druntime.environment=integrationdev
Since this now works out of the box with Spring profiles, this command line argument changes to:
-Dspring.profiles.active=integrationdev
The old style of
-Druntime.environment
will still work for the time being
Using the Spring Environment
Since all of our out-of-the-box Broadleaf properties work with Spring Profiles, that also means that they support obtaining properties from the Spring Environment. While we will continue support the Broadleaf SystemPropertiesService
we recommend updating your code to instead use the Spring Environment
:
@Component
public class MyComponent {
@Autowired
private Environment env;
}
Accessing the
SystemPropertiesService
statically withBLCSystemProperty.resolveSystemProperty()
is deprecated
Removal of the Broadleaf XML merge process
Prior to 5.2.0-GA Broadleaf had a very unique way that we bootstrapped our Spring XML configuration. This involved reading through all of the Broadleaf configuration files along with all user-defined configuration files, merging them together via some pre-defined rules and then presenting the final version to Spring. This represented a fair amount of technical debt for us as it required us to consider this every time we wanted to apply Broadleaf configuration to anywhere Spring was used (e.g. Spring Boot, Spring Test). We have thus rewritten the portions of code that required this with Spring and instead rely on BeanPostProcessor
s to merge together the definitions of various beans.
For example, in Broadleaf 5.1 and below, adding an Activity
to the blCheckoutWorkflow
looked like this:
<bean id="blCheckoutWorkflow" class="org.broadleafcommerce.core.workflow.SequenceProcessor">
<property name="activities">
<list>
<bean p:order="9999999" class="com.mycompany.worklow.checkout.SendOrderConfirmationEmailActivity" />
</list>
</property>
</bean>
This customized definition for blCheckoutWorfklow
was then merged in with the original definition in Broadleaf. In Broadleaf 5.2, this has changed to the following XML:
<bean id="customCheckoutActivities" class="org.springframework.beans.factory.config.ListFactoryBean">
<property name="sourceList">
<list>
<bean p:order="9999999" class="com.mycompany.worklow.checkout.SendOrderConfirmationEmailActivity" />
</list>
</property>
</bean>
<bean class="org.broadleafcommerce.common.extensibility.context.merge.LateStageMergeBeanPostProcessor">
<property name="collectionRef" value="customCheckoutActivities"/>
<property name="targetRef" value="blCheckoutWorkflowActivities"/>
</bean>
or in Java config:
@Configuration
public class MyConfiguration {
@Bean
public Activity orderConfirmationActivity() {
Activity confirmation = new SendOrderConfirmationEmailActivity();
confirmation.setOrder(9999999);
return confirmation;
}
@Merge("blCheckoutWorkflowActivities")
public List customCheckoutActivities() {
return Arrays.asList(orderConfirmationActivity());
}
}
More information on the beans that were effected by this change are in the 5.1 to 5.2.0 Migration Notes.
Spring integration testing support
Our integration testing with Spring has been improved quite a bit. To get started, add the Broadleaf integration
dependencies along with spring-test
:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.broadleafcommerce</groupId>
<artifactId>integration</artifactId>
<version>${blc.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.broadleafcommerce</groupId>
<artifactId>integration</artifactId>
<version>${blc.version}</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
Both the
<classifier>tests</classifer>
and non-classifier versions ofintegration
are required
You can then decide which testing library you would like to use. We support Spock, JUnit and TestNG. Here is an example using JUnit:
@RunWith(SpringRunner.class)
@BroadleafSiteIntegrationTest
public class JUnitTest {
@Resource
private CatalogService catalogService;
@Test
public void testInjectionWorks() {
Assert.assertNotEquals(catalogService, null);
}
}
For more information check out Integration testing with Broadleaf.
Spring Boot Support
Broadleaf now has built in support for Spring Boot. All of the Broadleaf getting started documentation and how to use Broadleaf is all based on Spring Boot.
Better annotation-based autoconfiguration support
Using Broadleaf in various other Spring applications has gotten easier. Now instead of requiring a web.xml
or a customized version of Spring's ApplicationContext
class this is as simple as annotating a configuration class with:
@Configuration
@EnableBroadleafSiteAutoConfiguration
public class BroadleafApplication {
}
See EnableBroadleafSiteAutoConfiguration.java for more information.
First-class Java @Configuration
support
Java-style @Configuration
classes are now fully supported. This style was generally popularized by Spring Boot but Boot is by no means required. You can do what you did with Broadleaf beans in XML in Java configuration instead. The following example illustrates an override of Broadleaf's CatalogService
as well as a customization to the blCheckoutWorkflow
:
@Configuration
public class BroadleafOverrides {
// equivalent to <bean id="blCatalogService" class="com.mycompany.MyCatalogService" />
@Bean
public CatalogService blCatalogService() {
return new MyCatalogService();
}
/**
* Equivalent to:
* <bean id="customCheckoutActivities" class="org.springframework.beans.factory.config.ListFactoryBean">
* <property name="sourceList">
* <list>
* <bean class="com.mycompany.workflow.checkout.MyCustomActivity" />
* </list>
* </property>
* </bean>
* <bean class="org.broadleafcommerce.common.extensibility.context.merge.LateStageMergeBeanPostProcessor">
* <property name="collectionRef" value="customCheckoutActivities"/>
* <property name="targetRef" value="blCheckoutWorkflowActivities"/>
* </bean>
*
*/
@Merge("blCheckoutWorkflow")
public List myNewCheckoutActivities() {
return Arrays.asList(myCustomActivity());
}
@Bean
public Activity myCustomActivity() {
return new MyCustomActivity();
}
}
New annotations
@Merge
- shorthand for theLateStageMergeBeanPostProcessor
andEarlyStageMergeBeanPostProcessor
to modify internal Broadleaf configuration@ConditionalOnBroadleafModule
- allows conditional bean registration/configuration if a particular Broadleaf module is loaded@ConditionalOnAdmin
/@ConditionalOnNotAdmin
- conditional bean registration/configuration if only in the Broadleaf admin