SpringAOP在项目中的简单应用(二)

2014-11-23 23:37:56 · 作者: · 浏览: 1
配置动态数据源,现网的应用有可能要访问云平台数据库的需要。

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 部分。

下面给