Автор оригинала: Vlad Mihalcea.
Вступление
Мне нравится использовать шаблон builder всякий раз, когда объект имеет как обязательные, так и необязательные свойства. Но создание объектов обычно является обязанностью Spring framework , поэтому давайте посмотрим, как вы можете использовать его, используя конфигурации Spring на основе Java и XML.
Пример строителя
Давайте начнем со следующего класса конструктора.
public final class Configurationextends ConfigurationProperties > { public static final long DEFAULT_METRIC_LOG_REPORTER_MILLIS = TimeUnit.MINUTES.toMillis(5); public static class Builder { private final String uniqueName; private final T targetDataSource; private final PoolAdapterFactory poolAdapterFactory; private MetricsFactory metricsFactory; private ConnectionProxyFactory connectionProxyFactory = ConnectionDecoratorFactoryResolver.INSTANCE.resolve(); private boolean jmxEnabled = true; private boolean jmxAutoStart = false; private long metricLogReporterMillis = DEFAULT_METRIC_LOG_REPORTER_MILLIS; private EventListenerResolver eventListenerResolver; private long connectionAcquireTimeThresholdMillis = Long.MAX_VALUE; private long connectionLeaseTimeThresholdMillis = Long.MAX_VALUE; public Builder( String uniqueName, T targetDataSource, PoolAdapterFactory poolAdapterFactory) { this.uniqueName = uniqueName; this.targetDataSource = targetDataSource; this.poolAdapterFactory = poolAdapterFactory; } public Builder setMetricsFactory( MetricsFactory metricsFactory) { this.metricsFactory = metricsFactory; return this; } public Builder setConnectionProxyFactory( ConnectionProxyFactory connectionProxyFactory) { this.connectionProxyFactory = connectionProxyFactory; return this; } public Builder setJmxEnabled( boolean enableJmx) { this.jmxEnabled = enableJmx; return this; } public Builder setJmxAutoStart( boolean jmxAutoStart) { this.jmxAutoStart = jmxAutoStart; return this; } public Builder setMetricLogReporterMillis( long metricLogReporterMillis) { this.metricLogReporterMillis = metricLogReporterMillis; return this; } public Builder setEventListenerResolver( EventListenerResolver eventListenerResolver) { this.eventListenerResolver = eventListenerResolver; return this; } public Builder setConnectionAcquireTimeThresholdMillis( Long connectionAcquireTimeThresholdMillis) { if (connectionAcquireTimeThresholdMillis != null) { this.connectionAcquireTimeThresholdMillis = connectionAcquireTimeThresholdMillis; } return this; } public Builder setConnectionLeaseTimeThresholdMillis( Long connectionLeaseTimeThresholdMillis) { if (connectionLeaseTimeThresholdMillis != null) { this.connectionLeaseTimeThresholdMillis = connectionLeaseTimeThresholdMillis; } return this; } public Configuration build() { EventPublisher eventPublisher = EventPublisher.newInstance(eventListenerResolver); Configuration configuration = new Configuration ( uniqueName, targetDataSource, eventPublisher ); configuration.setJmxEnabled(jmxEnabled); configuration.setJmxAutoStart(jmxAutoStart); configuration.setMetricLogReporterMillis(metricLogReporterMillis); configuration.setConnectionAcquireTimeThresholdMillis(connectionAcquireTimeThresholdMillis); configuration.setConnectionLeaseTimeThresholdMillis(connectionLeaseTimeThresholdMillis); if(metricsFactory == null) { metricsFactory = MetricsFactoryResolver.INSTANCE.resolve(); } configuration.metrics = metricsFactory.newInstance(configuration); configuration.poolAdapter = poolAdapterFactory.newInstance(configuration); configuration.connectionProxyFactory = connectionProxyFactory; return configuration; } } private final T targetDataSource; private Metrics metrics; private PoolAdapter poolAdapter; private ConnectionProxyFactory connectionProxyFactory; private Configuration( String uniqueName, T targetDataSource, EventPublisher eventPublisher) { super(uniqueName, eventPublisher); this.targetDataSource = targetDataSource; } public T getTargetDataSource() { return targetDataSource; } public Metrics getMetrics() { return metrics; } public PoolAdapter getPoolAdapter() { return poolAdapter; } public ConnectionProxyFactory getConnectionProxyFactory() { return connectionProxyFactory; } }
Конфигурация на основе Java
Если вы используете конфигурацию Spring на основе Java , то вот как вы это сделаете:
@org.springframework.context.annotation.Configuration public class FlexyPoolConfiguration { @Autowired private AbstractDataSourceBean poolingDataSource; @Value("${flexy.pool.uniqueId}") private String uniqueId; @Bean public Configurationconfiguration() { return new Configuration.Builder<>( uniqueId, poolingDataSource, AtomikosPoolAdapter.FACTORY ) .setJmxEnabled(true) .setMetricLogReporterMillis(TimeUnit.SECONDS.toMillis(5)) .build(); } @Bean(initMethod = "start", destroyMethod = "stop") public FlexyPoolDataSource dataSource() { Configuration configuration = configuration(); return new FlexyPoolDataSource ( configuration, new IncrementPoolOnTimeoutConnectionAcquiringStrategy.Factory(5), new RetryConnectionAcquiringStrategy.Factory(2) ); } }
Конфигурация на основе XML
Конфигурация на основе XML более подробна и не так интуитивно понятна, как конфигурация на основе Java:
Потрясающе, правда?
Вывод
Вы можете использовать шаблон компоновщика независимо от того, какой режим конфигурации Spring вы уже выбрали. Если у вас есть сомнения в его полезности, вот три веские причины вы должны быть в курсе.