溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Spring使用自定義注解及Aspect實現(xiàn)數(shù)據(jù)庫切換

發(fā)布時間:2020-11-03 16:47:44 來源:億速云 閱讀:268 作者:Leah 欄目:開發(fā)技術(shù)

Spring使用自定義注解及Aspect實現(xiàn)數(shù)據(jù)庫切換?針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

實現(xiàn)思路

重寫Spring的AbstractRoutingDataSource抽象類的determineCurrentLookupKey方法。

我們來看下Spring-AbstractRoutingDataSource的源碼

Spring使用自定義注解及Aspect實現(xiàn)數(shù)據(jù)庫切換

AbstractRoutingDataSource獲取數(shù)據(jù)源之前會先調(diào)用determineCurrentLookupKey方法查找當(dāng)前的lookupKey。

Object lookupKey = determineCurrentLookupKey();
DataSource dataSource = this.resolvedDataSources.get(lookupKey);
.......
return dataSource;

lookupKey為數(shù)據(jù)源標(biāo)識,因此通過重寫這個查找數(shù)據(jù)源標(biāo)識的方法就可以讓spring切換到指定的數(shù)據(jù)源.

從變量定義中可以知道resolvedDataSources為Map類型的對象。

private Map<Object, DataSource> resolvedDataSources;

示例

Spring使用自定義注解及Aspect實現(xiàn)數(shù)據(jù)庫切換

步驟一 新建Maven工程

依賴如下: pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.artisan</groupId>
	<artifactId>dynamicDataSource</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>dynamicDataSource</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<file.encoding>UTF-8</file.encoding>
		<spring.version>4.3.9.RELEASE</spring.version>
		<servlet.version>3.1.0</servlet.version>
		<aspectj.version>1.8.1</aspectj.version>
		<commons-dbcp.version>1.4</commons-dbcp.version>
		<jetty.version>8.1.8.v20121106</jetty.version>
		<log4j.version>1.2.17</log4j.version>
		<log4j2.version>2.8.2</log4j2.version>
		<testng.version>6.8.7</testng.version>
		<oracle.version>11.2.0.4.0</oracle.version>
		<jstl.version>1.2</jstl.version>
	</properties>

	<dependencies>
		<!-- spring 依賴 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>${commons-dbcp.version}</version>
		</dependency>


		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>${aspectj.version}</version>
		</dependency>


		<dependency>
			<groupId>org.testng</groupId>
			<artifactId>testng</artifactId>
			<version>${testng.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>

		<!-- oracle jdbc driver -->
		<dependency>
			<groupId>com.oracle</groupId>
			<artifactId>ojdbc6</artifactId>
			<version>${oracle.version}</version>
		</dependency>

		<dependency>
			<groupId>org.testng</groupId>
			<artifactId>testng</artifactId>
			<version>${testng.version}</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- 
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>
	 	-->
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>${log4j2.version}</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>${log4j2.version}</version>
		</dependency>
		
	</dependencies>

	<build>
		<!-- 使用JDK1.7編譯 -->
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

步驟二 繼承AbstractRoutingDataSource并重寫determineCurrentLookupKey方法獲取特定數(shù)據(jù)源

package com.artisan.dynamicDB;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

/**
 * 
 * 
 * @ClassName: DynamicDataSource
 * 
 * @Description: 
 *  AbstractRoutingDataSource中的抽象方法determineCurrentLookupKey是實現(xiàn)數(shù)據(jù)源的route的核心
 *  .需要重寫該方法
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年7月24日 下午8:28:46
 */
public class DynamicDataSource extends AbstractRoutingDataSource {

	@Override
	protected Object determineCurrentLookupKey() {
		return DynamicDataSourceHolder.getDataSource();
	}
}

步驟三 創(chuàng)建DynamicDataSourceHolder用于持有當(dāng)前線程中使用的數(shù)據(jù)源標(biāo)識

package com.artisan.dynamicDB;

/**
 * 
 * 
 * @ClassName: DynamicDataSourceHolder
 * 
 * @Description:創(chuàng)建DynamicDataSourceHolder用于持有當(dāng)前線程中使用的數(shù)據(jù)源標(biāo)識
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年7月24日 下午8:23:50
 */
public class DynamicDataSourceHolder {

 /**
 * 數(shù)據(jù)源標(biāo)識保存在線程變量中,避免多線程操作數(shù)據(jù)源時互相干擾
 */
 private static final ThreadLocal<String> dataSourceHolder = new ThreadLocal<String>();

 /**
 * 
 * 
 * @Title: setDataSource
 * 
 * @Description: 設(shè)置數(shù)據(jù)源
 * 
 * @param dataSource
 * 
 * @return: void
 */
 public static void setDataSource(String dataSource) {
 dataSourceHolder.set(dataSource);
 }

 /**
 * 
 * 
 * @Title: getDataSource
 * 
 * @Description: 獲取數(shù)據(jù)源
 * 
 * @return
 * 
 * @return: String
 */
 public static String getDataSource() {
 return dataSourceHolder.get();
 }

 /**
 * 
 * 
 * @Title: clearDataSource
 * 
 * @Description: 清除數(shù)據(jù)源
 * 
 * 
 * @return: void
 */
 public static void clearDataSource() {
 dataSourceHolder.remove();
 }
}

步驟四 配置多個數(shù)據(jù)源和DynamicDataSource的bean

<&#63;xml version="1.0" encoding="UTF-8" &#63;>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xmlns:p="http://www.springframework.org/schema/p"
 xmlns:context="http://www.springframework.org/schema/context"
 xmlns:aop="http://www.springframework.org/schema/aop" 
 xmlns:tx="http://www.springframework.org/schema/tx"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd
 http://www.springframework.org/schema/context 
 http://www.springframework.org/schema/context/spring-context.xsd
 http://www.springframework.org/schema/tx 
 http://www.springframework.org/schema/tx/spring-tx.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop.xsd
 http://www.springframework.org/schema/util 
 http://www.springframework.org/schema/util/spring-util.xsd">
 
 <!-- 基類包,將標(biāo)注Spring注解的類自動轉(zhuǎn)化Bean,同時完成Bean的注入 -->
 <context:component-scan base-package="com.artisan"/>
 
 <!-- 使用context命名空間,在xml文件中配置數(shù)據(jù)庫的properties文件 -->
 <context:property-placeholder location="classpath:jdbc.properties" />
 
 <!-- 配置數(shù)據(jù)源--> 
 
 <!-- 主站點的數(shù)據(jù)源 -->
 <bean id="dataSourcePR" class="org.apache.commons.dbcp.BasicDataSource" 
 destroy-method="close"
 p:driverClassName="${jdbc.driverClassNamePR}"
 p:url="${jdbc.urlPR}"
 p:username="${jdbc.usernamePR}"
 p:password="${jdbc.passwordPR}" />
 
 <!-- 備用站點的數(shù)據(jù)源 -->
 <bean id="dataSourceDR" class="org.apache.commons.dbcp.BasicDataSource" 
 destroy-method="close"
 p:driverClassName="${jdbc.driverClassNameDR}"
 p:url="${jdbc.urlDR}"
 p:username="${jdbc.usernameDR}"
 p:password="${jdbc.passwordDR}" /> 
 
 <!-- 主站點cc實例數(shù)據(jù)源 -->
 <bean id="dataSourceCC" class="org.apache.commons.dbcp.BasicDataSource" 
 destroy-method="close"
 p:driverClassName="${jdbc.driverClassNameCC}"
 p:url="${jdbc.urlCC}"
 p:username="${jdbc.usernameCC}"
 p:password="${jdbc.passwordCC}" />


 <bean id="dynamicDataSource" class="com.artisan.dynamicDB.DynamicDataSource">
 <property name="targetDataSources" ref="dynamicDatasourceMap" />
 <!-- 默認數(shù)據(jù)源 -->
 <property name="defaultTargetDataSource" ref="dataSourcePR" />
 </bean>
 
 <!-- 指定lookupKey和與之對應(yīng)的數(shù)據(jù)源 -->
 <util:map id="dynamicDatasourceMap" key-type="java.lang.String">
 <entry key="dataSourcePR" value-ref="dataSourcePR" />
 <entry key="dataSourceDR" value-ref="dataSourceDR" />
 <entry key="dataSourceCC" value-ref="dataSourceCC" />
 </util:map>
 
 
 <!-- 配置Jdbc模板 JdbcTemplate使用動態(tài)數(shù)據(jù)源的配置 -->
 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
 p:dataSource-ref="dynamicDataSource" />
 
 <!-- 配置數(shù)據(jù)源注解的攔截規(guī)則,比如攔截service層或者dao層的所有方法,這里攔截了com.artisan下的全部方法 --> 
 <bean id="dataSourceAspect" class="com.artisan.dynamicDB.DataSourceAspect" />
 <aop:config>
  <aop:aspect ref="dataSourceAspect">
  <!-- 攔截所有XXX方法 -->
  <aop:pointcut id="dataSourcePointcut" expression="execution(* com.artisan..*(..))"/>
  <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
  </aop:aspect>
 </aop:config>
 
 <!-- 配置事務(wù)管理器 -->
 <bean id="transactionManager"
 class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
 p:dataSource-ref="dynamicDataSource" />
 
 <!-- 通過AOP配置提供事務(wù)增強,讓com.artisan包下所有Bean的所有方法擁有事務(wù) -->
 <aop:config proxy-target-class="true">
 <aop:pointcut id="serviceMethod"
 expression="(execution(* com.artisan..*(..))) and (@annotation(org.springframework.transaction.annotation.Transactional))" />
 <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice" />
 </aop:config>
 <tx:advice id="txAdvice" transaction-manager="transactionManager">
 <tx:attributes>
 <tx:method name="*" />
 </tx:attributes>
 </tx:advice>
</beans>

配置到這里,我們就可以使用多個數(shù)據(jù)源了,只需要在操作數(shù)據(jù)庫之前只要DynamicDataSourceHolder.setDataSource(“dataSourcePR”)即可切換到數(shù)據(jù)源dataSourcePR并對數(shù)據(jù)庫dataSourcePR進行操作了。

問題:每次使用都需要調(diào)用DynamicDataSourceHolder#setDataSource,十分繁瑣,并且難以維護。

我們可以通過Spring的AOP和注解, 直接通過注解的方式指定需要訪問的數(shù)據(jù)源。 繼續(xù)改進下吧

步驟五 定義名為@DataSource的注解

package com.artisan.dynamicDB;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 
 * 
 * @ClassName: DataSource 
 * 
 * 
 * @Description: 注解@DataSource既可以加在方法上,也可以加在接口或者接口的實現(xiàn)類上,優(yōu)先級別:方法>實現(xiàn)類>接口。
 *  如果接口、接口實現(xiàn)類以及方法上分別加了@DataSource注解來指定數(shù)據(jù)源,則優(yōu)先以方法上指定的為準(zhǔn)。
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年7月24日 下午9:59:29
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataSource {
 // 和配置文件中 dynamicDatasourceMap中的key保持一致
 public static String PR_RB = "dataSourcePR";

 public static String DR_RB = "dataSourceDR";

 public static String PR_CC = "dataSourceCC";

 /**
 * 
 * 
 * @Title: name
 * 
 * @Description: 如果僅標(biāo)注@DataSource 默認為PR_RB數(shù)據(jù)庫實例
 * 
 * @return
 * 
 * @return: String
 */
 String name() default DataSource.PR_RB;

}

步驟六 定義AOP切面以便攔截所有帶有注解@DataSource的方法,取出注解的值作為數(shù)據(jù)源標(biāo)識放到DynamicDataSourceHolder的線程變量中

package com.artisan.dynamicDB;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;

/**
 * 
 * 
 * @ClassName: DataSourceAspect
 * 
 * @Description: 
 *  定義AOP切面以便攔截所有帶有注解@DataSource的方法,取出注解的值作為數(shù)據(jù)源標(biāo)識放到DBContextHolder的線程變量中
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年7月25日 上午10:51:41
 */
public class DataSourceAspect {

 /**
 * 
 * 
 * @Title: intercept
 * 
 * @Description: 攔截目標(biāo)方法,獲取由@DataSource指定的數(shù)據(jù)源標(biāo)識,設(shè)置到線程存儲中以便切換數(shù)據(jù)源
 * 
 * @param point
 * @throws Exception
 * 
 * @return: void
 */
 public void intercept(JoinPoint point) throws Exception {
 Class<&#63;> target = point.getTarget().getClass();
 MethodSignature signature = (MethodSignature) point.getSignature();
 // 默認使用目標(biāo)類型的注解,如果沒有則使用其實現(xiàn)接口的注解
 for (Class<&#63;> clazz : target.getInterfaces()) {
 resolveDataSource(clazz, signature.getMethod());
 }
 resolveDataSource(target, signature.getMethod());
 }

 /**
 * 
 * 
 * @Title: resolveDataSource
 * 
 * @Description: 提取目標(biāo)對象方法注解和類型注解中的數(shù)據(jù)源標(biāo)識
 * 
 * @param clazz
 * @param method
 * 
 * @return: void
 */
 private void resolveDataSource(Class<&#63;> clazz, Method method) {
 try {
 Class<&#63;>[] types = method.getParameterTypes();
 // 默認使用類型注解
 if (clazz.isAnnotationPresent(DataSource.class)) {
 DataSource source = clazz.getAnnotation(DataSource.class);
 DynamicDataSourceHolder.setDataSource(source.name());
 }
 // 方法注解可以覆蓋類型注解
 Method m = clazz.getMethod(method.getName(), types);
 if (m != null && m.isAnnotationPresent(DataSource.class)) {
 DataSource source = m.getAnnotation(DataSource.class);
 DynamicDataSourceHolder.setDataSource(source.name());
 }
 } catch (Exception e) {
 System.out.println(clazz + ":" + e.getMessage());
 }
 }
}

步驟七 在spring配置文件中配置攔截規(guī)則

 <!-- 配置數(shù)據(jù)源注解的攔截規(guī)則,比如攔截service層或者dao層的所有方法,這里攔截了com.artisan下的全部方法 --> 
 <bean id="dataSourceAspect" class="com.artisan.dynamicDB.DataSourceAspect" />
 <aop:config>
  <aop:aspect ref="dataSourceAspect">
  <!-- 攔截所有XXX方法 -->
  <aop:pointcut id="dataSourcePointcut" expression="execution(* com.artisan..*(..))"/>
  <aop:before pointcut-ref="dataSourcePointcut" method="intercept" />
  </aop:aspect>
 </aop:config>

步驟八 使用注解切換多數(shù)據(jù)源

ExtractDataService.java
package com.artisan.extractService;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Service;

import com.artisan.dynamicDB.DataSource;

/**
 * 
 * 
 * @ClassName: ExtractDataService
 * 
 * @Description: 業(yè)務(wù)類,這里暫時作為測試多數(shù)據(jù)源切換用
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年7月24日 下午9:07:38
 */

@Service
public class ExtractDataService {

 private static final Logger logger = LogManager
 .getLogger(ExtractDataService.class.getName());

 private JdbcTemplate jdbcTemplate;

 @Autowired
 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 this.jdbcTemplate = jdbcTemplate;
 }

 /**
 * 
 * 
 * @Title: selectDataFromPR
 * 
 * @Description:
 * 
 * 
 * @return: void
 */
 @DataSource(name = DataSource.PR_RB)
 public void selectDataFromPR_RB() {
 String sql = "select subs_id from owe_event_charge where event_inst_id = 10229001 ";

 jdbcTemplate.query(sql, new RowCallbackHandler() {

 @Override
 public void processRow(ResultSet rs) throws SQLException {
 logger.info(rs.getInt("subs_id"));
 }
 });
 }

 @DataSource(name = DataSource.DR_RB)
 public void selectDataFromDR_RB() {
 // 改為通過注解指定DB
 // DynamicDataSourceHolder.setDataSource(DBContextHolder.DATA_SOURCE_DR);
 String sql = " select a.task_comments from nm_task_type a where a.task_name = 'ALARM_LOG_LEVEL' ";
 jdbcTemplate.query(sql, new RowCallbackHandler() {

 @Override
 public void processRow(ResultSet rs) throws SQLException {
 logger.info(rs.getString("task_comments"));
 }
 });
 }

 @DataSource(name = DataSource.PR_CC)
 public void selectDataFromPR_CC() {
 // DBContextHolder.setDataSource(DBContextHolder.DATA_SOURCE_CC);
 String sql = "select acc_nbr from acc_nbr where acc_nbr_id = 82233858 ";
 jdbcTemplate.query(sql, new RowCallbackHandler() {

 @Override
 public void processRow(ResultSet rs) throws SQLException {
 logger.info(rs.getString("acc_nbr"));
 }
 });

 }
}

步驟九 測試

package com.artisan;
import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import com.artisan.extractService.ExtractDataService;

/**
 * 
 * 
 * @ClassName: App
 * 
 * @Description: 入口類
 * 
 * @author: Mr.Yang
 * 
 * @date: 2017年7月24日 下午8:50:25
 */
public class App {
 public static void main(String[] args) {
 try {
 // 加載日志框架 log4j2
 LoggerContext context = (LoggerContext) LogManager
 .getContext(false);
 ResourceLoader loader = new PathMatchingResourcePatternResolver();
 Resource resource = loader.getResource("classpath:log4j2.xml");

 context.setConfigLocation(resource.getFile().toURI());

 // 加載spring配置信息
 ApplicationContext ctx = new ClassPathXmlApplicationContext(
 "classpath:spring-context.xml");
 // 從容器中獲取Bean
 ExtractDataService service = ctx.getBean("extractDataService",
 ExtractDataService.class);
 // 從PR的RB實例中獲取數(shù)據(jù)
 service.selectDataFromPR_RB();
 // 從DR的RB實例中獲取數(shù)據(jù)
 service.selectDataFromDR_RB();
 // 從PR的CC實例中獲取數(shù)據(jù)
 service.selectDataFromPR_CC();

 } catch (IOException e) {
 e.printStackTrace();
 }

 }
}

其他代碼

log4j2.xml

<&#63;xml version="1.0" encoding="UTF-8"&#63;>
<!-- log4j2使用說明:
使用方式如下:
private static final Logger logger = LogManager.getLogger(實際類名.class.getName());
-->

<!--日志級別以及優(yōu)先級排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,這個用于設(shè)置log4j2自身內(nèi)部的信息輸出,可以不設(shè)置,當(dāng)設(shè)置成trace時,你會看到log4j2內(nèi)部各種詳細輸出-->
<!--monitorInterval:Log4j能夠自動檢測修改配置 文件和重新配置本身,設(shè)置間隔秒數(shù)-->
<configuration status="info" monitorInterval="180">

 <!-- 文件路徑和文件名稱,方便后面引用 -->
 <Properties>
 <Property name="backupFilePatch">D:/workspace/workspace-sts/backupOracle/log/</Property>
 <Property name="fileName">backupOracle.log</Property>
 </Properties>
 <!--先定義所有的appender-->
 <appenders>
 <!--這個輸出控制臺的配置-->
 <Console name="Console" target="SYSTEM_OUT">
  <!--控制臺只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch)-->
  <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />
  <!-- 輸出日志的格式-->
  <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n" />
 </Console>
 
 <!--這個會打印出所有的信息,每次大小超過size,則這size大小的日志會自動存入按年份-月份建立的文件夾下面并進行壓縮,作為存檔-->
 <RollingFile name="RollingFile" fileName="${backupFilePatch}${fileName}"
  filePattern="${backupFilePatch}$${date:yyyy-MM}/app-%d{yyyyMMddHHmmssSSS}.log.gz">
  <PatternLayout
  pattern="%d{yyyy.MM.dd 'at' HH:mm:ss.SSS z} %-5level %class{36} %L %M - %msg%xEx%n" />
  <!-- 日志文件大小 -->
  <SizeBasedTriggeringPolicy size="20MB" />
  <!-- 最多保留文件數(shù) DefaultRolloverStrategy屬性如不設(shè)置,則默認為最多同一文件夾下7個文件,這里設(shè)置了20 -->
  <DefaultRolloverStrategy max="20"/>
 </RollingFile>
 </appenders>
 
 <!--然后定義logger,只有定義了logger并引入的appender,appender才會生效-->
 <loggers>
 <!--過濾掉spring和mybatis的一些無用的DEBUG信息-->
 <logger name="org.springframework" level="INFO"></logger>
 <logger name="org.mybatis" level="INFO"></logger>
 <root level="trace"> 
  <appender-ref ref="RollingFile"/> 
  <appender-ref ref="Console"/> 
  </root> 
 </loggers>
</configuration>

jdbc.properties

##########################
##
##
## dbcp datasource pool ,basic configuration first.
## the other parameters keep default for now , you can change them if you want 
##
##
##########################

#Database in Lapaz
jdbc.driverClassNamePR=oracle.jdbc.driver.OracleDriver
jdbc.urlPR=jdbc:oracle:thin:@172.25.243.4:1521:xx
jdbc.usernamePR=xxx
jdbc.passwordPR=xxxxxxxx

#Database in Scluz
jdbc.driverClassNameDR=oracle.jdbc.driver.OracleDriver
jdbc.urlDR=jdbc:oracle:thin:@172.25.246.1:1521:xx
jdbc.usernameDR=xxx
jdbc.passwordDR=xxxxxxx

#Database in Lapaz
jdbc.driverClassNameCC=oracle.jdbc.driver.OracleDriver
jdbc.urlCC=jdbc:oracle:thin:@172.25.243.3:1521:xx
jdbc.usernameCC=xxx
jdbc.passwordCC=xxxxxx

運行結(jié)果:

Spring使用自定義注解及Aspect實現(xiàn)數(shù)據(jù)庫切換

關(guān)于Spring使用自定義注解及Aspect實現(xiàn)數(shù)據(jù)庫切換問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI