66 lines
2.1 KiB
Markdown
66 lines
2.1 KiB
Markdown
# CLAUDE.md - system-dynamic-datasource
|
|||
|
|
|
||
|
|
This file provides guidance to Claude Code when working in the system-dynamic-datasource module.
|
||
|
|
|
||
|
|
## Purpose
|
||
|
|
|
||
|
|
Provides dynamic multi-datasource switching at runtime using Spring's `AbstractRoutingDataSource`. This module has no main class and is not runnable on its own.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
@DataSource (annotation)
|
||
|
|
↓ triggers
|
||
|
|
DataSourceAspect (AOP around advice)
|
||
|
|
↓ sets/clears
|
||
|
|
DynamicContextHolder (ThreadLocal<Deque<String>>)
|
||
|
|
↓ peek() returns key to
|
||
|
|
DynamicDataSource (extends AbstractRoutingDataSource)
|
||
|
|
↓ routes to
|
||
|
|
Multiple DataSources (configured in DynamicDataSourceProperties)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Key Classes
|
||
|
|
|
||
|
|
### `@DataSource` annotation
|
||
|
|
|
||
|
|
Apply to methods or classes to specify which datasource to use. Takes a datasource name string.
|
||
|
|
|
||
|
|
### `DataSourceAspect`
|
||
|
|
|
||
|
|
AOP aspect that intercepts `@DataSource`-annotated methods. Before invocation, pushes the datasource name onto `DynamicContextHolder`. After invocation (finally block), pops it back off.
|
||
|
|
|
||
|
|
### `DynamicContextHolder`
|
||
|
|
|
||
|
|
Thread-safe holder using `ThreadLocal<Deque<String>>`. Uses a deque (stack) to support nested `@DataSource` calls -- each method restores the previous datasource on exit.
|
||
|
|
- `push(String ds)` -- set current datasource
|
||
|
|
- `poll()` -- restore previous
|
||
|
|
- `peek()` -- get current (used by DynamicDataSource)
|
||
|
|
|
||
|
|
### `DynamicDataSource extends AbstractRoutingDataSource`
|
||
|
|
|
||
|
|
`determineCurrentLookupKey()` returns `DynamicContextHolder.peek()`. If the holder is empty, falls back to the default datasource.
|
||
|
|
|
||
|
|
### `DynamicDataSourceFactory`
|
||
|
|
|
||
|
|
Creates Druid datasource instances from configuration properties.
|
||
|
|
|
||
|
|
### Configuration Properties
|
||
|
|
|
||
|
|
`DynamicDataSourceProperties`: Maps to YAML `spring.datasource.dynamic.*` with multiple named datasource configs.
|
||
|
|
`DataSourceProperties`: Individual datasource config (url, username, password, driver-class-name, etc.).
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
```java
|
||
|
|
@Service
|
||
|
|
public class SomeService {
|
||
|
|
@DataSource("oracle")
|
||
|
|
public List<Data> queryFromOracle() {
|
||
|
|
// queries run against the "oracle" datasource
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
When no `@DataSource` is present, queries use the default (primary) datasource configured in `application-*.yml`.
|