Dao.xml配置如下(这里用到c3p0数据库连接池,数据库操作用springJDBC):
动态数据库类如下结构(这里借鉴了网上的实现):
DataSorceEntry.为接口:
public interface DataSourceEntry {
// 云平台数据源标志
public final static String YUN_SOURCE = "dataSource2";
// 现网数据源标志
public final static String CURR_SOURCE = "dataSource";
/**
* 还原数据源
*
*/
public void restore();
/**
* 切换数据源
*/
public void switchSource();
/**
* 设置数据源
*
* @param dataSource
*/
public void set(String source);
/**
* 获取数据源
*
* @return String
*/
public String get();
/**
* 清空数据源
*/
public void clear();
}
DataSourceEntryImpl为DataSorceEntry的实现类:
public class DataSourceEntryImpl implements DataSourceEntry {
private final static ThreadLocal
local = new ThreadLocal
(); public void clear() { local.remove(); } public String get() { return local.get(); } public void restore() { local.set(null); // 设置null数据源 } public void set(String source) { local.set(source); } public void switchSource() { if (DataSourceEntry.CURR_SOURCE.equals(get())) { set(DataSourceEntry.YUN_SOURCE); }else { set(DataSourceEntry.CURR_SOURCE); } } }
DynamicDataSource则为继承AbstractRoutingDataSource(springjdbc的多数据源路由类)类,该类以DataSorceEntry的实例作为数据源选择类,以注入方式实现:
public class DynamicDataSource extends AbstractRoutingDataSource {
@Autowired
private DataSourceEntry dataSourceEntry;
@Override
protected Object determineCurrentLookupKey() {
return this.dataSourceEntry.get();
}
@Resource
public void setDataSourceEntry(DataSourceEntry dataSourceEntry) {
this.dataSourceEntry = dataSourceEntry;
}
}
改造实例
这里以其中一个改造实进行说明,为了简单化,这里就举一个某个子系统的登录验证功能来说明,因为该子系统在并行期间是不做割接的,所以用户验证需访问两个平台的数据库。
DaYiAspest.java:
@Component
@Aspect
public class DaYiAspest{
@Autowired
private DataSourceEntry dataSourceEntry;//动态数据源
//配置切入点集合
@Pointcut("execution(* cn.qtone.xxt.parentnew.kwfd.controller.*.dayi(..)) " +
"|| execution(* cn.qtone.xxt.schoolnew.kjck.controller.*.dayi(..))" +
"|| execution(* cn.qtone.xxt.studentnew.kwfd.controller.*.dayi(..))")
public void pointcuts(){}
/**
* 单点登陆 (切入替换原方法)
*
* @param request
* @param response
* @return
* @throws IOException
*/
@Around( value = "pointcuts()")
public Object dayiLoginInit(ProceedingJoinPoint pjp) throws IOException {
HttpServletRequest request = (HttpServletRequest) pjp.getArgs()[0];
HttpServletResponse response = (HttpServletResponse) pjp.getArgs()[1];
Object obj = null;
//执行方法前操作
obj = pjp.proceed();// 执行原操作
//执行原方法后操作
return obj;
}
}
说明:@Pointcut可以定义多个切入点集合,也可以直接@Around( “execution表达式"),这里介绍一下execution表达式:
Spring AOP 用户可能会经常使用execution pointcut designator。执行表达式的格式如下:
execution(modifiers-pattern ret-type-pattern declaring-type-pattern name-pattern(param-pattern)throws-pattern )除了返回类型模式(上面代码片断中的ret-type-pattern),名字模式和参数模式以外,所有的部分都是可选的。返回类型模式决定了方法的返回类型必须依次匹配一个连接点。你会使用的最频繁的返回类型模式是 *,它代表了匹配任意的返回类型。一个全称限定的类型名将只会匹配返回给定类型的方法。名字模式匹配的是方法名。你可以使用 * 通配符作为所有或者部分命名模式。参数模式稍微有点复杂:() 匹配了一个不接受任何参数的方法,而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。模式 (*) 匹配了一个接受一个任何类型的参数的方法。模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。请参见AspectJ编程指南的 Language Semantics 部分。
下面给