Рубрики
Без рубрики

Шаблон конструктора и пружинный каркас

Автор оригинала: Vlad Mihalcea.

Вступление

Мне нравится использовать шаблон builder всякий раз, когда объект имеет как обязательные, так и необязательные свойства. Но создание объектов обычно является обязанностью Spring framework , поэтому давайте посмотрим, как вы можете использовать его, используя конфигурации Spring на основе Java и XML.

Пример строителя

Давайте начнем со следующего класса конструктора.

public final class Configuration 
         extends 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 Configuration configuration() {
        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 вы уже выбрали. Если у вас есть сомнения в его полезности, вот три веские причины вы должны быть в курсе.