Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

The Builder Pattern and the Spring Framework

DZone's Guide to

The Builder Pattern and the Spring Framework

Learn how to to use the Spring framework and the builder pattern.

· Java Zone
Free Resource

Managing a MongoDB deployment? Take a load off and live migrate to MongoDB Atlas, the official automated service, with little to no downtime.

I like to make use of the builder pattern whenever an object has both mandatory and optional properties. But building objects is usually the Spring framework responsibility, so let’s see how you can employ it using both Java and XML-based Spring configurations.

A Builder example

Let’s start from the following Builder class.

public final class Configuration<T extends DataSource> extends ConfigurationProperties<T, Metrics, PoolAdapter<T>> {
public static final long DEFAULT_METRIC_LOG_REPORTER_PERIOD = 5;
public static class Builder<T extends DataSource> {
private final String uniqueName;
private final T targetDataSource;
private final PoolAdapterBuilder<T> poolAdapterBuilder;
private final MetricsBuilder metricsBuilder;
private boolean jmxEnabled = true;
private long metricLogReporterPeriod = DEFAULT_METRIC_LOG_REPORTER_PERIOD;
public Builder(String uniqueName, T targetDataSource, MetricsBuilder metricsBuilder, PoolAdapterBuilder<T> poolAdapterBuilder) {
this.uniqueName = uniqueName;
this.targetDataSource = targetDataSource;
this.metricsBuilder = metricsBuilder;
this.poolAdapterBuilder = poolAdapterBuilder;
}
public Builder setJmxEnabled(boolean enableJmx) {
this.jmxEnabled = enableJmx;
return this;
}
public Builder setMetricLogReporterPeriod(long metricLogReporterPeriod) {
this.metricLogReporterPeriod = metricLogReporterPeriod;
return this;
}
public Configuration<T> build() {
Configuration<T> configuration = new Configuration<T>(uniqueName, targetDataSource);
configuration.setJmxEnabled(jmxEnabled);
configuration.setMetricLogReporterPeriod(metricLogReporterPeriod);
configuration.metrics = metricsBuilder.build(configuration);
configuration.poolAdapter = poolAdapterBuilder.build(configuration);
return configuration;
}
}
private final T targetDataSource;
private Metrics metrics;
private PoolAdapter poolAdapter;
private Configuration(String uniqueName, T targetDataSource) {
super(uniqueName);
this.targetDataSource = targetDataSource;
}
public T getTargetDataSource() {
return targetDataSource;
}
public Metrics getMetrics() {
return metrics;
}
public PoolAdapter<T> getPoolAdapter() {
return poolAdapter;
}
}

Java-based configuration

If you’re using Spring Java-based configuration then this is how you’d do it:

@org.springframework.context.annotation.Configuration
public class FlexyDataSourceConfiguration {
@Autowired
private PoolingDataSource poolingDataSource;
@Bean
public Configuration configuration() {
return new Configuration.Builder(
UUID.randomUUID().toString(),
poolingDataSource,
CodahaleMetrics.BUILDER,
BitronixPoolAdapter.BUILDER
).build();
}
@Bean(initMethod = "start", destroyMethod = "stop")
public FlexyPoolDataSource dataSource() {
Configuration configuration = configuration();
return new FlexyPoolDataSource(configuration,
new IncrementPoolOnTimeoutConnectionAcquiringStrategy.Builder(5),
new RetryConnectionAcquiringStrategy.Builder(2)
);
}
}

If you enjoy reading this article, you might want to subscribe to my newsletter and get a discount for my book as well.

Vlad Mihalcea&apos;s Newsletter

XML-based configuration

The XML-based configuration is more verbose and not as intuitive as the Java-based configuration:

<bean id="configurationBuilder" class="com.vladmihalcea.flexypool.config.Configuration$Builder">
<constructor-arg value="uniqueId"/>
<constructor-arg ref="poolingDataSource"/>
<constructor-arg value="#{ T(com.vladmihalcea.flexypool.metric.codahale.CodahaleMetrics).BUILDER }"/>
<constructor-arg value="#{ T(com.vladmihalcea.flexypool.adaptor.BitronixPoolAdapter).BUILDER }"/>
</bean>
<bean id="configuration" factory-bean="configurationBuilder" factory-method="build"/>
<bean id="dataSource" class="com.vladmihalcea.flexypool.FlexyPoolDataSource" init-method="start" destroy-method="stop">
<constructor-arg ref="configuration"/>
<constructor-arg>
<array>
<bean class="com.vladmihalcea.flexypool.strategy.IncrementPoolOnTimeoutConnectionAcquiringStrategy$Builder">
<constructor-arg value="5"/>
</bean>
<bean class="com.vladmihalcea.flexypool.strategy.RetryConnectionAcquiringStrategy$Builder">
<constructor-arg value="2"/>
</bean>
</array>
</constructor-arg>
</bean>

If you enjoyed this article, I bet you are going to love my book as well.






Conclusion

You can make use of the Builder pattern no matter the Spring configuration mode you’ve already chosen. If you have doubts about its usefulness, here are three compelling reasons you should be aware of.

If you have enjoyed reading my article and you’re looking forward to getting instant email notifications of my latest posts, you just need tofollow my blog.

MongoDB Atlas is the easiest way to run the fastest-growing database for modern applications — no installation, setup, or configuration required. Easily live migrate an existing workload or start with 512MB of storage for free.

Topics:
java ,devops ,spring

Published at DZone with permission of Vlad Mihalcea. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}