使用反射实现接口引擎

先介绍一下活动模块的背景

  • 活动主要关系活动表和环节表,每个活动有特定的n个环节
  • 活动主要分为两部分(我总结的):
  • (1)、活动页面交互环节(intercation),由用户主动调用服务
  • (2)、程序主动行为(automation),有用户活动期间投资或者新用户注册触发行为

1、新的活动引擎中,新增一个活动基类接口:
只有一个抽象方法,用于引擎自动执行的行为(例如投资以后送红包,以及新注册用户赠送礼物)

/**
 * user zyu
 * datetime 2017/3/22 13:34
 * description
 */
public interface IBaseActivity {
    void autoMation(Map<String,Object> parmMap);
}

2、活动具体实现类,实现IBaseActivity接口

/**
 * user zyu
 * datetime 2017/3/22 13:41
 * description 活动模板
 */
@Service("simpleActivity")
public class SimpleActivity implements IBaseActivity {

    /**
     * method1
     * @param parmMap
     * @return
     */
    public ReturnResult<Map<String,Object>> method1(Map<String,Object> parmMap){
        /**
         * 逻辑实现
         * 返回数据
         */
        return null;
    }

    /**
     * method2
     * @param parmMap
     * @return
     */
    public ReturnResult<Map<String,Object>> method2(Map<String,Object> parmMap){
        /**
         * 逻辑实现
         * 返回数据
         */
        return null;
    }

    @Override
    public void autoMation(Map<String, Object> parmMap) {
        /**
         * 引擎自动行为逻辑实现
         */
    }
}

3、提供通用的活动接口,用于引擎实例(通过Spring 反射实现),这里还要说一点,主要是踩的坑,开始使用的java原生的反射,但是spring 注入的机制就失效了,只能通过手动装配,这点网上大致是这么解释的:因为通过java原生的反射,没有创建类实例,所以类中的注入就不起作用

装载 baseActivity,这里的baseActivity是IBaseActivity类型

/**
 * load baseActivity
 * 装载 baseActivity
 */
if(activityMap.containsKey(activityCode)){
	baseActivity = activityMap.get(activityCode);
}else {
	ActivityInfo activityInfo = activityInfoService.getActivityInfoByCode(activityCode);
	if(null !=activityInfo && null != activityInfo.getReflexClass()
         && !activityInfo.getReflexClass().equals("")){
		baseActivity = SpringContextHolder.getBean(activityInfo.getReflexClass());
		activityMap.put(activityCode , baseActivity);
	}else {
		resultData.setResultCode(0);
		resultData.setErrorCode(ErrorConstants.PARAM_NOT_RIGHT);
		printJson(resultData);
		return null;
	}
}

装载 method,方法名主要有调用服务方传递

/**
 * load aClass and method
 * 装载 aClass method
 */
if(metMap.containsKey((activityCode+methodName))){
	method = metMap.get((activityCode+methodName));
}else {
	if(classMap.containsKey(activityCode+"class")){
		aClass = classMap.get(activityCode+"class");
	}else {
		aClass = baseActivity.getClass();
		classMap.put((activityCode+"class") ,aClass);
	}
	method =  ReflectionUtils.findMethod(aClass, methodName, Map.class);
	metMap.put((activityCode+methodName) ,method);
}
resultData = (ReturnResult<Map<String, Object>>) ReflectionUtils.invokeMethod(method, baseActivity,parmMap);

出于性能考虑,增加了缓存机制

/**
 * cache class and method
 * 缓存反射类和方法
 */
public static Map<String,Class> classMap = new HashMap<String,Class>();
public static Map<String,IBaseActivity> activityMap = new HashMap<String,IBaseActivity>();
public static Map<String,Method> metMap = new HashMap<String,Method>();

4、修改表结构,在活动表中增加COLUMN1字段,用于存放SimpleActivity活动实现类的@Service注解;
而在环节表中增加COLUMN2字段,用于存放环节类型(主要有intercation和automation,具体解释参照上面)

5、在投资或者注册以后有一个映射类(此类的作用就是用作,活动期间投资送礼物和注册赠送礼品什么的),在此类的映射方法中使用反射,具体实现如下:

/**
 * use new activity engine
 * 使用新的活动引擎
 */
ActivityLink activityLink1 = activityLinkDao.findAutoMationLinkByActivityCode(activityCode);
if (null != activityLink1) {
	try {
		Map<String, Object> parmMap = new HashMap<String, Object>();
		IBaseActivity baseActivity = null;
		if (activityMap.containsKey(activityCode)) {
			baseActivity = activityMap.get(activityCode);
		} else {
			if (null != ai && null != ai.getReflexClass()
				&& !ai.getReflexClass().equals("")) {
				baseActivity = SpringContextHolder.getBean(ai.getReflexClass());
				activityMap.put(activityCode, baseActivity);
			}
		}
		if (null != baseActivity) {
			parmMap.put("parm1", null);
			parmMap.put("parm2", null);
			parmMap.put("parm3", null);
			baseActivity.autoMation(parmMap);
		}
	} catch (Exception e) {
	e.printStackTrace();
	}
}
/** new **/

使用这种模式主要有几点好处:

1、简化接口(活动模块提供一个通用接口)
2、增强可读性的可维护性
3、活动模块化,降低耦合度
4、插拔式

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值