복붙노트

[SPRING] Spring : 빌더 패턴을 사용하여 빈 작성하기

SPRING

Spring : 빌더 패턴을 사용하여 빈 작성하기

ektorp를 사용하여 CouchDB에 연결합니다.

ektorp HttpClient 인스턴스를 작성하는 방법은 빌더 패턴을 사용하는 것입니다.

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

나는 비교적 새로운 봄입니다. 작성자를 통해 내 컨텍스트에서 HttpClient를 구성하는 방법에 대한 조언을 구하십시오.

이 작업을 수행하는 한 가지 방법은 @Configuration을 사용하는 것입니다. 다른 옵션이 있습니까?

해결법

  1. ==============================

    1.FactoryBean 인터페이스를 구현하려고 할 수 있습니다 :

    FactoryBean 인터페이스를 구현하려고 할 수 있습니다 :

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

    그리고 다음 bean 정의를 config에 추가합니다 :

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

    그런 다음이 bean을 다른 bean에 주입 할 수 있습니다.이 bean은 StdHttpClient 인스턴스로 해석됩니다.

  2. ==============================

    2.나는 flex-pool (반응 연결 풀 크기 조정 유틸리티)을 개발할 때 같은 문제를 한 번 발견했기 때문에 Java 기반 및 XML 기반 예제를 모두 포함하는 기사를 작성했습니다.

    나는 flex-pool (반응 연결 풀 크기 조정 유틸리티)을 개발할 때 같은 문제를 한 번 발견했기 때문에 Java 기반 및 XML 기반 예제를 모두 포함하는 기사를 작성했습니다.

    기본적으로 다음 빌더에서 시작합니다.

    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 기반 구성을 사용하는 것은 간단합니다.

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

    그러나 XML 기반 구성도 사용할 수 있습니다.

    <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"/>
    
  3. ==============================

    3.Spring FactoryBean과 FactoryMethod 문서를 확인하십시오.

    Spring FactoryBean과 FactoryMethod 문서를 확인하십시오.

  4. ==============================

    4.당신의 사건에 대해 명백한 것은 아니지만; 빌더가 표준 빈 패턴 세트 메소드를 통해 특성을 노출하는 경우 빌더를 확장 할 수 있습니다. 즉, org.apache.httpcomponents : httpclient HttpClientBuilder를 예로 들자면 다음과 같은 것을 가질 수 있습니다 :

    당신의 사건에 대해 명백한 것은 아니지만; 빌더가 표준 빈 패턴 세트 메소드를 통해 특성을 노출하는 경우 빌더를 확장 할 수 있습니다. 즉, org.apache.httpcomponents : httpclient HttpClientBuilder를 예로 들자면 다음과 같은 것을 가질 수 있습니다 :

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

    이제 HttpClientBuilder에 의해 노출 된 모든 메소드는 팩토리 빈에 액세스 할 수 있습니다. 이제 다음과 같은 구성이 가능합니다.

    <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. from https://stackoverflow.com/questions/3236850/spring-using-builder-pattern-to-create-a-bean by cc-by-sa and MIT license