All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.springframework.jdbc.datasource.lookup.RoutingDataSource Maven / Gradle / Ivy

package org.springframework.jdbc.datasource.lookup;

import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;

/**
 * 
 * PropertiesConfigurationFactory propertiesConfigurationFactory = new PropertiesConfigurationFactory(DataSourceProperties.class);
 * propertiesConfigurationFactory.setPropertySources(new PropertySourcesBinder(new ResourcePropertySource(resource)).getPropertySources());
 * DataSource dataSource = propertiesConfigurationFactory.getObject().initializeDataSourceBuilder().build();
 * 
* * @see net.ttddyy.dsproxy.listener.AbstractQueryLoggingListener * @see net.ttddyy.dsproxy.listener.CommonsQueryLoggingListener * @see net.ttddyy.dsproxy.listener.SLF4JQueryLoggingListener * @see net.ttddyy.dsproxy.listener.SLF4JQueryLoggingListener * @see org.springframework.beans.BeanUtils#instantiate(Class) * @see org.springframework.util.ReflectionUtils#findMethod(Class, String) * @see org.springframework.util.ReflectionUtils#invokeMethod(java.lang.reflect.Method, * Object, Object...) * @see org.springframework.core.Constants#asString(String) * @see org.springframework.util.CollectionUtils#toMultiValueMap(Map) */ public final class RoutingDataSource extends org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource { private final MultiValueMap readOnly = new LinkedMultiValueMap(); private final int size; /** * @see java.util.Collections#addAll(Collection, Object...) * @see java.util.Collections#synchronizedList(List) * @see org.springframework.core.io.ContextResource#getPathWithinContext() */ public RoutingDataSource(Map dataSources) { Assert.notEmpty(dataSources, "'dataSources' must have entries"); this.size = dataSources.size(); for (Entry entry : dataSources.entrySet()) { String key = String.valueOf(entry.getKey()); this.readOnly.add(key.toLowerCase().startsWith(org.springframework.transaction.support.DefaultTransactionDefinition.READ_ONLY_MARKER.toLowerCase()), entry.getKey()); } setTargetDataSources(dataSources); setLenientFallback(false); } /** * @see org.springframework.util.ClassUtils#isPresent(String, ClassLoader) * @see org.springframework.util.ClassUtils#getConstructorIfAvailable(Class, Class...) * @see org.springframework.beans.BeanUtils#instantiateClass(Constructor, Object...) * @see org.springframework.util.Assert#isAssignable(Class, Class) * @see org.springframework.beans.BeanUtils#instantiate(Class) * @see org.springframework.util.CollectionUtils#findCommonElementType(Collection) * @see org.springframework.transaction.annotation.Isolation#DEFAULT */ @Override protected Object determineCurrentLookupKey() { if (this.size == 1) { return null; } boolean readOnly = TransactionSynchronizationManager.isCurrentTransactionReadOnly(); List list = this.readOnly.getOrDefault(readOnly, this.readOnly.get(!readOnly)); Assert.notEmpty(list, "'dataSource' must have elements"); Collections.shuffle(list); Object key = list.iterator().next(); if (logger.isTraceEnabled()) { logger.trace("key: " + key); logger.trace("readOnly: " + readOnly); logger.trace("name: " + TransactionSynchronizationManager.getCurrentTransactionName()); Integer isolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel(); if (isolationLevel != null) { for (Isolation isolation : Isolation.values()) { if (isolation.value() == isolationLevel.intValue()) { logger.trace("isolationLevel: " + isolation + "(" + isolationLevel + ")"); } } } } return key; } }