1. 程式人生 > >第九章 springboot + mybatis + 多數據源 (AOP實現)

第九章 springboot + mybatis + 多數據源 (AOP實現)

app aps 基礎上 default round mapper lan efault epo

在第八章 springboot + mybatis + 多數據源代碼的基礎上,做兩點修改

1、ShopDao

技術分享
package com.xxx.firstboot.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.xxx.firstboot.domain.Shop;
import com.xxx.firstboot.mapper.ShopMapper;

@Repository
public class ShopDao { @Autowired private ShopMapper mapper; /** * 獲取shop */ public Shop getShop(int id) { return mapper.getShop(id); } }
View Code

說明:只是去掉了設置數據源key的那一句代碼

2、DataSourceAspect

技術分享
package com.xxx.firstboot.common.datasource;

import
org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; import com.xxx.firstboot.dao.ShopDao; @Aspect @Component public class DataSourceAspect { @Before("execution(* com.xxx.firstboot.dao.*.*(..))")
public void setDataSourceKey(JoinPoint point){ //連接點所屬的類實例是ShopDao if(point.getTarget() instanceof ShopDao){ DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2); }else{//連接點所屬的類實例是UserDao(當然,這一步也可以不寫,因為defaultTargertDataSource就是該類所用的mytestdb) DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb); } } // @Around("execution(* com.xxx.firstboot.dao.*.*(..))") // public Object setDataSourceKeyByAround(ProceedingJoinPoint point) throws Throwable{ // if(point.getTarget() instanceof ShopDao){ // DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2); // }else{//連接點所屬的類實例是UserDao(當然,這一步也可以不寫,因為defaultTargertDataSource就是該類所用的mytestdb) // DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb); // } // return point.proceed();//執行目標方法 // } }
View Code

說明:列出了兩種切面方法,在這裏推薦使用前者,原因:

  • @Around:需要寫執行目標方法的那一行代碼,而這一行代碼可能會拋異常,還需要拋出或捕獲

對於切點表達式,可以抽取出來,進行重復利用。如上代碼可以改為如下:

技術分享
package com.xxx.firstboot.common.datasource;

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;

import com.xxx.firstboot.dao.ShopDao;

@Aspect
@Component
public class DataSourceAspect {

    /**
     * 使用空方法定義切點表達式
     */
    @Pointcut("execution(* com.xxx.firstboot.dao.*.*(..))")
    public void declareJointPointExpression() {
    }

    /**
     * 使用定義切點表達式的方法進行切點表達式的引入
     */
    @Before("declareJointPointExpression()")
    public void setDataSourceKey(JoinPoint point) {
        // 連接點所屬的類實例是ShopDao
        if (point.getTarget() instanceof ShopDao) {
            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb2);
        } else {// 連接點所屬的類實例是UserDao(當然,這一步也可以不寫,因為defaultTargertDataSource就是該類所用的mytestdb)
            DatabaseContextHolder.setDatabaseType(DatabaseType.mytestdb);
        }
    }

}
View Code

註意:該切點表達式也可以用在其他切面類中,引入的時候使用"全類名.切點方法名()",例:@Before("com.xxx.firstboot.common.datasource.DataSourceAspect.declareJointPointExpression()")

第九章 springboot + mybatis + 多數據源 (AOP實現)