I use ektorp to connect to CouchDB.
The way to build an ektorp HttpClient
instance is to use builder pattern:
HttpClient httpClient = new StdHttpClient.Builder() .host("mychouchdbhost") .port(4455) .build();
I am relatively new to Spring. Please advice me on how I can configure an HttpClient
in my context to create it via the Builder
.
One way to do this is with @Configuration
. Are any other options?
The builder pattern allows you to enforce a step-by-step process to construct a complex object as a finished product. In this pattern, the step-by-step construction process remains same but the finished products can have different representations.
Builder pattern aims to “Separate the construction of a complex object from its representation so that the same construction process can create different representations.” It is used to construct a complex object step by step and the final step will return the object.
In the Application , we create a bean, call its method and set up the Spring Boot application. The CommandLineRunner interface indicates that a bean should run when it is contained within a SpringApplication . It can be used to create command line applications in Spring Boot.
You may try to implement FactoryBean
interface:
public class HttpFactoryBean implements FactoryBean<HttpClient>{ private String host; private int port; public HttpClient getObject() throws Exception { return new StdHttpClient.Builder() .host(host) .port(port) .build(); } public Class<? extends HttpClient> getObjectType() { return StdHttpClient.class; } public boolean isSingleton() { return true; } public void setHost(String host) { this.host = host; } public void setPort(int port) { this.port = port; }}
And add to config following bean definition:
<beans ..."> <bean name="myHttpClient" class="HttpFactoryBean"> <property name="port" value="8080"/> <property name="host" value="localhost"/> </bean> </beans>
Then you can inject this bean to another beans, it will be resolved as StdHttpClient
instance.
I once stumbled on the same issue when I was developing FlexyPool, so this is what I did.
Basically, starting from the following Builder:
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; } }
Using the Java-based configuration is straight-forward:
@org.springframework.context.annotation.Configuration public class FlexyDataSourceConfiguration { @Bean public Configuration configuration() { return new Configuration.Builder( UUID.randomUUID().toString(), poolingDataSource, CodahaleMetrics.BUILDER, BitronixPoolAdapter.BUILDER ).build(); } }
But you can also use XML-based configuration as well:
<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"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With