配置多个数据源时Spring Aop不生效。。无法自动切换数据源。

乐之者v 2018-06-21 04:39:03
我得配好几个数据源,以下是我手动切换数据源的代码:

public class WorkOrderTest {
public static void main(String[] args) {
ApplicationContext applicationContext=new ClassPathXmlApplicationContext(new String[]{"spring-mvc.xml","spring-mybatis.xml"});
WorkOrderService workOrderService=(WorkOrderService) applicationContext.getBean("workOrderService");
// MultipleDataSource.setDataSourceKey("vso1DataSource"); //这一句是手动切换数据源的代码。手动切换没问题。
Long id=100000004220380L;
WorkOrder workOrder= workOrderService.selectByPrimaryKey(id);
System.out.println("===================>BillId:"+workOrder.getBillId());
}
}

我通过 MultipleDataSource.setDataSourceKey("vso1DataSource"); 切换数据源就没问题。。但是通过aop切换就一直没法生效。
csdn改版了?剩下代码没法贴出来。我放楼下。
...全文
1007 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
stacksoverflow 2018-06-21
  • 打赏
  • 举报
回复
增强AOP,通过反射,获取数据源环境。
参考
http://www.linhao007.com/2017/11/23/01/
乐之者v 2018-06-21
  • 打赏
  • 举报
回复
MultipleDataSourceAspectAdvice里面关于aop的代码,已经被注入到Spring了。
我在代码中加入构造函数,这一句打印出来了。
既然检测到了aop的代码,为什么aop不生效??难道是我的pointCut里面的表达式有问题?还是我的其他配置有问题?

public MultipleDataSourceAspectAdvice(){
System.out.println("==========================>MultipleDataSourceAspectAdvice构造函数。");
}
诺丽果 2018-06-21
  • 打赏
  • 举报
回复
csdn的这个改版我也是醉了,还是以前的好,不要这么多天花乱坠的,实用简便最好,程序员不怎么追求美观
诺丽果 2018-06-21
  • 打赏
  • 举报
回复
我用的也是数据库工具切换类来切换数据库的,还没用过aop切换
stacksoverflow 2018-06-21
  • 打赏
  • 举报
回复
引用 7 楼 sinat_32502451 的回复:
[quote=引用 2 楼 stacksoverflow 的回复:]
service的方法执行前会启动事务
也就是你对AOP的配置要在事务启动前进行数据源的切换。


这个我查过。加了注解@Order(0),好像可以使aop代码在事务之前执行。[/quote]
我没研究过这部分源代码,你确定是在获取Connection前吗?
如果是下面的顺序的话,恐怕会有问题
Connection conn = getConnectionByDataSource()
切换数据源
conn.beginTransection
执行方法...
乐之者v 2018-06-21
  • 打赏
  • 举报
回复
引用 2 楼 stacksoverflow 的回复:
service的方法执行前会启动事务
也就是你对AOP的配置要在事务启动前进行数据源的切换。


这个我查过。加了注解@Order(0),好像可以使aop代码在事务之前执行。
乐之者v 2018-06-21
  • 打赏
  • 举报
回复
ServiceImpl代码如下:
这个注解@Service("workOrderService"),放在接口和实现类上,都无法使aop生效。

public class WorkOrderServiceImpl implements WorkOrderService{
@Autowired
private WorkOrderDao workOrderDao;

@Override
public WorkOrder selectByPrimaryKey(Long id) {
return workOrderDao.selectByPrimaryKey(id);
}
}
乐之者v 2018-06-21
  • 打赏
  • 举报
回复
上面的部分代码被吞了。最后面是 return jp.proceed();
下面这个是配置数据源的代码:

/**
* 配置多个数据源
*/
public class MultipleDataSource extends AbstractRoutingDataSource {
private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>();

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

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


以下是Dao层:

public interface WorkOrderDao {
WorkOrder selectByPrimaryKey(@Param("id") Long id);
}

以下是Service层:

@Service("workOrderService")
public interface WorkOrderService {

WorkOrder selectByPrimaryKey(Long id);

}
stacksoverflow 2018-06-21
  • 打赏
  • 举报
回复
csdn这个改版我给管理员提bug了,估计是输入字符限制的地方少写了个0。本来1万字变成1千字了。
stacksoverflow 2018-06-21
  • 打赏
  • 举报
回复
切点有执行顺序吧,查一查,要赶在启动事务前把数据源切换掉。
stacksoverflow 2018-06-21
  • 打赏
  • 举报
回复
service的方法执行前会启动事务
也就是你对AOP的配置要在事务启动前进行数据源的切换。
乐之者v 2018-06-21
  • 打赏
  • 举报
回复
以下是aop的代码:

/**
* 通过aop在每次调用前自动切换数据源。不用手动切换。
*/
@Component
@Aspect
@Order(0)
public class MultipleDataSourceAspectAdvice {
@Pointcut("execution (* com.cmsz.crm..*.*(..))")
private void cutMethod() {} // 声明一个切入点,cutMethod为切入点名称

//此处拦截的类,或者方法,需要修改。。不正确的话,无法拦截。
@Around("cutMethod()")
public Object doAround(ProceedingJoinPoint jp) throws Throwable {
System.out.println("==========================>开始进行aop操作:");
if (jp.getTarget() instanceof EsbTraceDao) {
MultipleDataSource.setDataSourceKey("vbaseDataSource");
} else if (jp.getTarget() instanceof WorkOrderDao) {
MultipleDataSource.setDataSourceKey("vso1DataSource");
}else {
System.out.println("==================>proceedingJoinPoint.getTarget():"+jp.getTarget());
}
return jp.proce


每一层楼只能贴一部分代码。。csdn这个改版,我醉了。

81,122

社区成员

发帖
与我相关
我的任务
社区描述
Java Web 开发
社区管理员
  • Web 开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧