• 通过spring来配置某个命令号和执行方法之间的映射


    整理的内容

    1.手动获取spring的ApplicationContext和bean对象

    写一个工具类实现ApplicationContextAware接口

    2.反射的知识整理

    3.前后端协议交互的时使用命令号,可以方便调用后端的执行方法

    定义一个对象:ActionDefine,表示消息编号与消息处理类的映射定义

    package com.youxigu.dynasty2.core.flex;
    
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.youxigu.dynasty2.util.StringUtils;
    import com.youxigu.wolf.net.codec.IAMF3Message;
    
    /**
     * 消息编号与消息处理类的映射定义
     * 
     * @author Administrator
     * 
     */
    public class ActionDefine {
        /**
         * 消息编号
         */
        private int cmd;
    
        /**
         * 消息处理类
         */
        private Object bean;
        /**
         * 消息处理类的处理方法
         */
        private String methodName;
    
        /**
         * 传入参数的类型
         */
        private Class<? extends IAMF3Message> inParmClass;
    
        /**
         * 返回参数的类型
         */
        private Class<? extends IAMF3Message> outParmClass;
    
        /**
         * 缓存Method实例,避免每次都查找Method
         */
        private transient Method method;
        private transient Method prevMethod;
    
        public Method getMethod() {
            return method;
        }
    
        public void setMethod(Method method) {
            this.method = method;
        }
    
        public Method getPrevMethod() {
            return prevMethod;
        }
    
        public void setPrevMethod(Method prevMethod) {
            this.prevMethod = prevMethod;
        }
    
        public int getCmd() {
            return cmd;
        }
    
        public void setCmd(int cmd) {
            this.cmd = cmd;
        }
    
        public Object getBean() {
            return bean;
        }
    
        public void setBean(Object bean) {
            this.bean = bean;
        }
    
        public String getMethodName() {
            return methodName;
        }
    
        public void setMethodName(String methodName) {
            this.methodName = methodName;
        }
    
        public Class<? extends IAMF3Message> getInParmClass() {
            return inParmClass;
        }
    
        public void setInParmClass(Class<? extends IAMF3Message> inParmClass) {
            this.inParmClass = inParmClass;
        }
    
        public Class<? extends IAMF3Message> getOutParmClass() {
            return outParmClass;
        }
    
        public void setOutParmClass(Class<? extends IAMF3Message> outParmClass) {
            this.outParmClass = outParmClass;
        }
    
    }

    spring配置文件中增加配置

    <beans xmlns="http://www.springframework.org/schema/beans"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xmlns:aop="http://www.springframework.org/schema/aop"
             xmlns:tx="http://www.springframework.org/schema/tx"
             xmlns:flex="http://www.springframework.org/schema/flex"
             xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
               http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
               http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd
               http://www.springframework.org/schema/flex http://www.springframework.org/schema/flex/spring-flex-1.0.xsd">
        <!-- 11001命令代表要执行friendAction类中findUser方法-->
        <bean class="com.youxigu.dynasty2.core.flex.ActionDefine">
           <property name="cmd" value="11001"/>
           <property name="bean" ref="friendAction"/>
           <property name="methodName" value="findUser"/>
        </bean>
      
        <!-- 申请好友-11002-->
        <bean class="com.youxigu.dynasty2.core.flex.ActionDefine">
           <property name="cmd" value="11002"/>
           <property name="bean" ref="friendAction"/>
           <property name="methodName" value="appFriend"/>
        </bean>
        
         ...略
    
    </beans>

    手动初始化所有的actio定义,创建cmd和method的映射

    实现类接口ApplicationContextAware 就要实现他的方法setApplicationContext(ApplicationContext ctx)

    package com.youxigu.dynasty2.core.protobuf;
    
    import java.lang.reflect.Field;
    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.concurrent.TimeoutException;
    
    import org.apache.mina.core.session.IoSession;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    
    import com.google.protobuf.Message;
    import com.manu.core.ServiceLocator;
    import com.youxigu.dynasty2.chat.EventMessage;
    import com.youxigu.dynasty2.chat.MessageFilter;
    import com.youxigu.dynasty2.chat.MessageFilter.FilterMessages;
    import com.youxigu.dynasty2.chat.client.IChatClientService;
    import com.youxigu.dynasty2.core.flex.ActionDefine;
    import com.youxigu.dynasty2.core.flex.amf.AMF3WolfService;
    import com.youxigu.dynasty2.core.flex.amf.IAMF3Action;
    import com.youxigu.dynasty2.user.service.IAccountService;
    import com.youxigu.dynasty2.util.BaseException;
    import com.youxigu.wolf.net.IInitListener;
    import com.youxigu.wolf.net.IWolfService;
    import com.youxigu.wolf.net.OnlineUserSessionManager;
    import com.youxigu.wolf.net.Response;
    import com.youxigu.wolf.net.ResultMgr;
    import com.youxigu.wolf.net.SocketContext;
    import com.youxigu.wolf.net.SyncWolfTask;
    import com.youxigu.wolf.net.UserSession;
    
    /**
     * 接收并处理所有Flex客户端的请求
     * 
     * @author Administrator
     * 
     */
    public class ProtobufWolfService implements IWolfService, IInitListener, ApplicationContextAware {
    
        public static Logger log = LoggerFactory.getLogger(AMF3WolfService.class);
    
        private Map<Integer, ActionDefine> actions = new HashMap<Integer, ActionDefine>();
        private List<ActionDefine> actionDefines;
    
        public void setActionDefines(List<ActionDefine> actionDefines) {
            this.actionDefines = actionDefines;
        }
    
        @Override
        public void setApplicationContext(ApplicationContext ctx) throws BeansException {
            if (actionDefines == null) {
                actionDefines = new ArrayList<ActionDefine>();
    
                while (ctx != null) {
    //遍历所有的配置文件
    //取出bean的类型为ActionDefine的所有bean Map
    <String, ActionDefine> maps = ctx.getBeansOfType(ActionDefine.class); if (maps.values() != null && maps.values().size() > 0) { actionDefines.addAll(maps.values()); } ctx = ctx.getParent(); } } if (actionDefines != null) { // 初始化ActionDefine
    //声明方法的传入值类型数组,后面会强制修改 Class[] paramsType = { Object.class, Response.class }; for (ActionDefine ad : actionDefines) { int cmd = ad.getCmd();//命令号 if (actions.containsKey(cmd)) { throw new BaseException("重复的命令号:" + cmd); } if (ad.getSubActionIds() == null) {try {
    //用方法名和传入值类型反射取到方法声明 Method m
    = ad.getBean().getClass().getDeclaredMethod(ad.getMethodName(), paramsType); ad.setMethod(m);//有了method声明就可以invoke来调用方法了 String beforeMethodName = ad.getPrevMethodName(); if (beforeMethodName != null && !"".equals(beforeMethodName)) { m = ad.getBean().getClass().getDeclaredMethod(beforeMethodName, paramsType); ad.setPrevMethod(m); } } catch (NoSuchMethodException e) { e.printStackTrace(); log.error("action mapping is error : cmd={}", cmd); } } actions.put(cmd, ad); } actionDefines.clear(); actionDefines = null; } } public void init() { } @Override public Object handleMessage(Response response, Object message) { if (message instanceof com.google.protobuf.Message) { com.google.protobuf.Message params = (com.google.protobuf.Message) message; try {
    //用名称反射取得字段声明 Field cmdF
    = params.getClass().getDeclaredField("cmd_"); if(cmdF != null) { cmdF.setAccessible(true);
    //用Filed取得字段值
    int cmd_ = cmdF.getInt(params);
    //取得缓存中方法声明 ActionDefine ad
    = actions.get(cmd_); Method m = null; int cmd = ad.getCmd(); if (actions != null) { ad = actions.get(cmd); if (ad != null) m = ad.getMethod(); } if (m == null) { throw new BaseException("错误的命令号:" + cmd); } //调用方法 Object retu_ = m.invoke(ad.getBean(), new Object[] { message, response }); // ........ } } catch (Exception e) { e.printStackTrace(); } } return null; } }
  • 相关阅读:
    next_permutation( ) 和prev_permutation( ) 全排列函数
    F
    STL入门
    H
    C
    提交按钮组件
    JScorllPane面板(带滚轮的JPane)
    JPanel画板
    网络布局管理器
    边界布局管理器
  • 原文地址:https://www.cnblogs.com/dagangzi/p/4760233.html
Copyright © 2020-2023  润新知