????5?????Spring AOP ????? dataSource ?? key ?????dataSource?????key??? dataSourceMaster ?? dataSourceSlave??
package net.aazj.aop;
import net.aazj.enums.DataSources;
import net.aazj.util.DataSourceTypeManager;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect    // for aop
@Component // for auto scan
@Order(0)  // execute before @Transactional
public class DataSourceInterceptor {
@Pointcut("execution(public * net.aazj.service..*.getUser(..))")
public void dataSourceSlave(){};
@Before("dataSourceSlave()")
public void before(JoinPoint jp) {
DataSourceTypeManager.set(DataSources.SLAVE);
}
// ... ...
}
???????????????????? Aspect ????????? @Before ??????? @Pointcut("execution(public * net.aazj.service..*.getUser(..))") ?е?????????????????? DataSourceTypeManager.set(DataSources.SLAVE) ?????? key ??????? DataSources.SLAVE?????? dataSource ?????key=DataSources.SLAVE ??? dataSourceSlave ???dataSource??????÷????????sql??????slave??????????(??????????1987??????????????Aspect????????????????????????л????????Aspect??????@Transactional???Aspect????У??????????????@Order(0)??????л??????????@Transactional???)??
??????????????????? DataSourceInterceptor  ??? Aspect?????н??и??????????壬??????service???????????????????????????dataSource??
?????????????????? Spring AOP ???????????????????????????
????6??AbstractRoutingDataSource???????
????ThreadLocalRountingDataSource?????AbstractRoutingDataSource????????????protected abstract Object determineCurrentLookupKey(); ????????????????·???????????????????????????????
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean
AbstractRoutingDataSource ????? InitializingBean ???spring????????bean????????InitializingBean????
void afterPropertiesSet() throws Exception; ???????AbstractRoutingDataSource????????????????
@Override
public void afterPropertiesSet() {
if (this.targetDataSources == null) {
throw new IllegalArgumentException("Property 'targetDataSources' is required");
}
this.resolvedDataSources = new HashMap<Object?? DataSource>(this.targetDataSources.size());
for (Map.Entry<Object?? Object> entry : this.targetDataSources.entrySet()) {
Object lookupKey = resolveSpecifiedLookupKey(entry.getKey());
DataSource dataSource = resolveSpecifiedDataSource(entry.getValue());
this.resolvedDataSources.put(lookupKey?? dataSource);
}
if (this.defaultTargetDataSource != null) {
this.resolvedDefaultDataSource = resolveSpecifiedDataSource(this.defaultTargetDataSource);
}
}
????targetDataSources ????????xml????????????? dataSourceMaster ?? dataSourceSlave. afterPropertiesSet?????????????
????dataSourceMaster ?? dataSourceSlave?????????HashMap——resolvedDataSources???????????? key ???map ?????????dataSource??
????????????? AbstractDataSource ????е? Connection getConnection() throws SQLException; ??????????
????@Override
????public Connection getConnection() throws SQLException {
????return determineTargetDataSource().getConnection();
????}
??????????? determineTargetDataSource()????????????????????????????????????? dataSource ??
????protected DataSource determineTargetDataSource() {
????Assert.notNull(this.resolvedDataSources?? "DataSource router not initialized");
????Object lookupKey = determineCurrentLookupKey();
????DataSource dataSource = this.resolvedDataSources.get(lookupKey);
????if (dataSource == null && (this.lenientFallback || lookupKey == null)) {
????dataSource = this.resolvedDefaultDataSource;
????}
????if (dataSource == null) {
????throw new IllegalStateException("Cannot determine target DataSource for lookup key [" + lookupKey + "]");
????}
????return dataSource;
????}
????Object lookupKey = determineCurrentLookupKey(); ?÷???????????????????л??ThreadLocal?б???? key ????????key??????afterPropertiesSet()?г?????????resolvedDataSources???map?л??key?????dataSource????ThreadLocal?б???? key ??????AOP?????????service?????????????ú???OK?????????
????7????? ThreadLocalRountingDataSource
???????????????????? master-slave ??????????????ж?? master ?????ж?? slave?????master??????HA?????????????master???????????л???????master???????????????LVS/Keepalived??????????????????????ThreadLocalRountingDataSource??????????????????????????????????????mysql??????????????????????slave???????????????????slave???????????????????????????????????????????LVS/Keepalived?????????????????????????ThreadLocalRountingDataSource??????
????3. ???
?????????????????????AOP????????
??????????????mybatis????????Hibernate??????????????á?