35

Uso ektorp para conectar a CouchDB.Primavera: uso de patrón de generador para crear un bean

La manera de construir una instancia EKTORP HttpClient es utilizar Builder:

HttpClient httpClient = new StdHttpClient.Builder() 
           .host("mychouchdbhost") 
           .port(4455) 
           .build(); 

Soy relativamente nuevo en la primavera. Por favor, avísenme sobre cómo puedo configurar un HttpClient en mi contexto para crearlo a través del Builder.

Una forma de hacerlo es con @Configuration. ¿Hay alguna otra opción?

Respuesta

42

Usted puede tratar de implementar FactoryBean interfaz:

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; 
}} 

Y añada en las configuraciones siguientes frijol definición:

<beans ..."> 
    <bean name="myHttpClient" class="HttpFactoryBean"> 
     <property name="port" value="8080"/> 
     <property name="host" value="localhost"/> 
    </bean> 
</beans> 

A continuación, se puede inyectar este grano a otros granos, que se resolverá como StdHttpClient ejemplo.

3

Consulte la documentación de Spring FactoryBean y FactoryMethod.

1

Aunque no es explícito para su caso; es posible ampliar un constructor si expone las propiedades a través de los métodos estándar de patrón de frijoles set. es decir, si tomamos el org.apache.httpcomponents:httpclientHttpClientBuilder como ejemplo podríamos tener lo siguiente:

public class HttpClientFactoryBean 
     extends HttpClientBuilder 
     implements InitializingBean, 
        FactoryBean<HttpClient> { 

    private HttpClient value; 

    @Override 
    public void afterPropertiesSet() throws Exception { 
     this.value = build(); 
    } 

    @Override 
    public HttpClient getObject() throws Exception { 
     return value; 
    } 

    @Override 
    public Class<?> getObjectType() { 
     return HttpClient.class; 
    } 

    @Override 
    public boolean isSingleton() { 
     return true; 
    } 

} 

Ahora, cualquier método expuesto por HttpClientBuilder es accesible a su grano de fábrica. Una configuración como la siguiente, ahora es posible:

<beans id="httpClient" class="com.drunkendev.factory.HttpClientFactoryBean"> 
    <beans name="defaultCredentialsProvider" ref="credentialsProvider"/> 
    <beans name="targetAuthenticationStrategy"> 
    <util:constant static-field="org.apache.http.impl.client.TargetAuthenticationStrategy.INSTANCE"/> 
    </beans> 
</beans> 
5

una vez que me encontré con el mismo problema, cuando se estaba desarrollando flexy-pool (a reactive connection pool sizing utility), así que escribí an article con A y un ejemplo basado en XML basado en Java.

Básicamente, a partir de la siguiente Constructor:

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; 
    } 
} 

Utilizando la configuración basada en Java es directa:

@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(); 
    } 
} 

Pero también se puede utilizar la configuración basada en XML, así:

<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"/> 
+0

Lea a través de su artículo. Me gustó de esta manera y lo encontré único. ¿Podrías ayudarme a entender la construcción de los dos últimos constructor-arg? No pude encontrar ninguna ayuda en la construcción BUILDER que se está utilizando allí. – rajneesh2k10

+1

Es un generador que toma otros constructores para resolver algunas dependencias. –

+0

Oh ... Entonces, "BUILDER" es propiedad de "CodahaleMetrics" y "BitronixPoolAdapter" si no se ha confundido. – rajneesh2k10

Cuestiones relacionadas