Spring configuration multiple data source process

Here, AOP interception annotations are used to switch data sources.
1. Add new data source information in the data source configuration file context.xml, so that there are multiple database services that can be accessed. Pay attention to distinguish the jndi name.
2. Add the connection configuration of the new data source in the spring configuration file (usually spring.xml).
3. Create a new multi-data source class (such as MultipleDataSource.java), which needs to inherit from org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource
a) Add static properties to save data source information. Because threads do not need to access each other's data sources, ThreadLocal is used here to save the data source information of each thread

private static final ThreadLocal<String> dataSourceKey

 b) Override the determineCurrentLookupKey() method. This method is used by spring jdbc to find data sources from targetDataSources. If it returns null, the default data source specified by defaultTargetDataSource is used (these properties are configured in step 4)

	@Override
	protected Object determineCurrentLookupKey() {
		return dataSourceKey.get();
	}

 c) Add a static setting method to set the data source for the current thread

	public static void setDataSourceKey(String dataSource) {
		dataSourceKey.set(dataSource);
	}

 d) Add a static cleanup method to use the default data source for unannotated methods

	public static void toDefault(){
		dataSourceKey.remove();
	}

 4. Add beans of multiple data source classes in spring.xml

	<bean id="multipleDataSource"	class="MultipleDataSource">
		<property name="defaultTargetDataSource" ref="{0}" />
		<property name="targetDataSources">
			<map>
				<entry key="key1" value-ref="{1}" />
				<entry key="key2" value-ref="{2}" />
			</map>
		</property>
	</bean>

 a) Configure the attribute defaultTargetDataSource, and the ref value is one of several database connections. When no data source is specified, this connection is used by default.
b) The configuration attribute targetDataSources, the entry key of the map is freely defined to identify different data sources, and the value-ref points to the corresponding database connection.
6. Add a new annotation class, which needs to contain a string attribute. Due to the combination of AOP, it is necessary to specify that the reflection period is available, and the annotation acts on the method:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface BiDSChoicer {
	String dsName();
}

 7. Create a new AOP notification class. We need to switch the data source before the method is executed, so we need to implement the org.springframework.aop.MethodBeforeAdvice interface and rewrite the before(Method method, Object[] args, Object target) method:

	@Override
	public void before(Method method, Object[] args, Object target) throws Throwable {
		BiDSChoicer annotation = method.getAnnotation(BiDSChoicer.class);
		if (annotation != null)
	FossMultipleDataSource.setDataSourceKey(annotation.dsName());
		else
			FossMultipleDataSource.toDefault();
	}

 8. Since the interface implementation is configured with transaction management, the priority of the transaction will be higher than the data source switching. Once the transaction is opened, it is invalid to switch the data source, so it is necessary to modify their order here.
a) The notification class should implement the org.springframework.core.Ordered interface, and rewrite the getOrder() method to make it return 1;

	@Override
	public int getOrder() {
		return 1;
	}

 b) Add order to 2 in the configuration of the transaction

<tx:annotation-driven transaction-manager="transactionManager" order="2" />

 In this way, Spring will execute the notification class method first, and then start the transaction.
9. Add the annotation @BiDSchoicer(dsName="dsname") to the interface method that needs to switch the data source (must be a method in the interface, invalid in the implementation method), and the attribute value must be the entry key of the configured targetDataSources attribute.
10. Create a new notification class bean in spring.xml, assuming the id is advice
11. Define the entry point, the expression attribute should be modified according to the situation, pointing to the implementation class

	<bean id="dspc"
class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
		<property name="expression"
			value="execution(public * .service..*.*(..))"/>
	</bean>

 12. Define the Notifier

	<bean id="defaultPointcutAdvisor " class="org.springframework.aop.support.DefaultPointcutAdvisor">
		<property name="advice" ref="advice" />
		<property name="pointcut" ref="dspc" />
	</bean>

 After this configuration, you only need to add annotations to the interface method of the data source to modify it. After AOP intercepts the method, the data source will be set first. If there is an annotation, it will be set according to the annotation attribute. If there is no annotation, the default data source will be used. For those not intercepted by AOP, the default data source is used.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326774724&siteId=291194637