当我们在处理业务的时候,可以借助spring来实现业务分离
首先我们可以定义2个注解类
-
/**
-
*
-
*/
-
package com.cn.common.core.annotion;
-
import java.lang.annotation.ElementType;
-
import java.lang.annotation.Retention;
-
import java.lang.annotation.RetentionPolicy;
-
import java.lang.annotation.Target;
-
/**
-
* 请求命令
-
*
-
*/
-
@Target(ElementType.METHOD)
-
@Retention(RetentionPolicy.RUNTIME)
-
public @interface SocketCommand {
-
/**
-
* 请求的命令号
-
* @return
-
*/
-
short cmd();
-
}
-
/**
-
*
-
*/
-
package com.cn.common.core.annotion;
-
import java.lang.annotation.ElementType;
-
import java.lang.annotation.Retention;
-
import java.lang.annotation.RetentionPolicy;
-
import java.lang.annotation.Target;
-
/**
-
* 请求模块
-
*
-
*/
-
@Target(ElementType.TYPE)
-
@Retention(RetentionPolicy.RUNTIME)
-
public @interface SocketModule {
-
/**
-
* 请求的模块号
-
* @return
-
*/
-
short module();
-
}
2我们可以在接口中使用该注解
-
package com.cn.client.module.chat.handler;
-
import com.cn.common.core.annotion.SocketCommand;
-
import com.cn.common.core.annotion.SocketModule;
-
import com.cn.common.module.ModuleId;
-
import com.cn.common.module.chat.ChatCmd;
-
import com.cn.common.module.chat.response.ChatResponse;
-
/**
-
* 聊天
-
* @author -琴兽-
-
*
-
*/
-
@SocketModule(module = ModuleId.CHAT)
-
public interface ChatHandler {
-
/**
-
* 发送广播消息回包
-
* @param resultCode
-
* @param data {@link null}
-
* @return
-
*/
-
@SocketCommand(cmd = ChatCmd.PUBLIC_CHAT)
-
public void publicChat(int resultCode, byte[] data);
-
/**
-
* 发送私人消息回包
-
* @param resultCode
-
* @param data {@link null}
-
* @return
-
*/
-
@SocketCommand(cmd = ChatCmd.PRIVATE_CHAT)
-
public void privateChat(int resultCode, byte[] data);
-
/**
-
* 收到推送聊天信息
-
* @param resultCode
-
* @param data {@link ChatResponse}
-
* @return
-
*/
-
@SocketCommand(cmd = ChatCmd.PUSHCHAT)
-
public void receieveMessage(int resultCode, byte[] data);
-
}
3我们可以利用BeanPostProcessor来实现注解扫描
-
package com.cn.client.scanner;
-
import java.lang.reflect.Method;
-
import org.springframework.beans.BeansException;
-
import org.springframework.beans.factory.config.BeanPostProcessor;
-
import org.springframework.stereotype.Component;
-
import com.cn.common.core.annotion.SocketCommand;
-
import com.cn.common.core.annotion.SocketModule;
-
/**
-
* handler扫描器
-
*
-
*/
-
@Component
-
public class HandlerScaner implements BeanPostProcessor {
-
@Override
-
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
-
return bean;
-
}
-
@Override
-
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
-
Class<? extends Object> clazz = bean.getClass();
-
Class<?>[] interfaces = clazz.getInterfaces();
-
if(interfaces != null && interfaces.length > 0){
-
//扫描类的所有接口父类
-
for (Class<?> interFace : interfaces) {
-
//判断是否为handler接口类
-
SocketModule socketModule = interFace.getAnnotation(SocketModule.class);
-
if (socketModule == null) {
-
continue;
-
}
-
//找出命令方法
-
Method[] methods = interFace.getMethods();
-
if(methods != null && methods.length > 0){
-
for(Method method : methods){
-
SocketCommand socketCommand = method.getAnnotation(SocketCommand.class);
-
if(socketCommand == null){
-
continue;
-
}
-
final short module = socketModule.module();
-
final short cmd = socketCommand.cmd();
-
if(InvokerHoler.getInvoker(module, cmd) == null){
-
InvokerHoler.addInvoker(module, cmd, Invoker.valueOf(method, bean));
-
}else{
-
System.out.println("重复命令:"+"module:"+module +" "+"cmd:" + cmd);
-
}
-
}
-
}
-
}
-
}
-
return bean;
-
}
-
}
-
package com.cn.client.scanner;
-
import java.lang.reflect.InvocationTargetException;
-
import java.lang.reflect.Method;
-
/**
-
* 命令执行器
-
*
-
*/
-
public class Invoker {
-
/**
-
* 方法
-
*/
-
private Method method;
-
/**
-
* 目标对象
-
*/
-
private Object target;
-
public static Invoker valueOf(Method method, Object target){
-
Invoker invoker = new Invoker();
-
invoker.setMethod(method);
-
invoker.setTarget(target);
-
return invoker;
-
}
-
/**
-
* 执行
-
* @param paramValues
-
* @return
-
* @throws InvocationTargetException
-
* @throws IllegalArgumentException
-
* @throws IllegalAccessException
-
*/
-
public Object invoke(Object... paramValues){
-
try {
-
return method.invoke(target, paramValues);
-
} catch (IllegalAccessException e) {
-
e.printStackTrace();
-
} catch (IllegalArgumentException e) {
-
e.printStackTrace();
-
} catch (InvocationTargetException e) {
-
e.printStackTrace();
-
}
-
return null;
-
}
-
public Method getMethod() {
-
return method;
-
}
-
public void setMethod(Method method) {
-
this.method = method;
-
}
-
public Object getTarget() {
-
return target;
-
}
-
public void setTarget(Object target) {
-
this.target = target;
-
}
-
}
-
package com.cn.client.scanner;
-
import java.util.HashMap;
-
import java.util.Map;
-
/**
-
* 命令执行器管理者
-
*
-
*/
-
public class InvokerHoler {
-
/**命令调用器*/
-
private static Map<Short, Map<Short, Invoker>> invokers = new HashMap<>();
-
/**
-
* 添加命令调用
-
* @param module
-
* @param cmd
-
* @param invoker
-
*/
-
public static void addInvoker(short module, short cmd, Invoker invoker){
-
Map<Short, Invoker> map = invokers.get(module);
-
if(map == null){
-
map = new HashMap<>();
-
invokers.put(module, map);
-
}
-
map.put(cmd, invoker);
-
}
-
/**
-
* 获取命令调用
-
* @param module
-
* @param cmd
-
* @param invoker
-
*/
-
public static Invoker getInvoker(short module, short cmd){
-
Map<Short, Invoker> map = invokers.get(module);
-
if(map != null){
-
return map.get(cmd);
-
}
-
return null;
-
}
-
}
接下来可以试试了
-
package com.cn.client;
-
import org.springframework.context.ApplicationContext;
-
import org.springframework.context.support.ClassPathXmlApplicationContext;
-
import com.cn.client.swing.Swingclient;
-
/**
-
* 启动函数
-
*
-
*/
-
public class ClientMain {
-
@SuppressWarnings("resource")
-
public static void main(String[] args) {
-
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
-
Swingclient swing = applicationContext.getBean(Swingclient.class);
-
swing.setVisible(true);
-
}
-
}
ok ,这种思想很好的,特此记录下