java服务器框架 | 您所在的位置:网站首页 › java服务端框架 › java服务器框架 |
注解: 大部分都用来设计JAVA框架 , 由于他的写法简单 , 重复利用高的特点。 注解用修饰符:@interface , 表示 , 实现了java.lang.annotation接口。属性 @Target , @Retention。 @Target 用来修饰类型, ElementType.TYPE 是用来修饰类, ElementType .METHOD , 是用来修饰方法。 @Retention 是运行类型 , RetentionPolicy.RUNTIME 运行当中的状态。 有方法 , 必须要加默认值 以下我们以前端发送来的消息为列: 找到对应的handler , 去处理对应的方法 例子如下: package com.game.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 类的注解 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface MessageAnnotation { /** * 开启还是关闭 */ boolean isGm() default true; } package com.game.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 方法的注解 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface MethodAnnotation { boolean isGm() default true; }修饰的类: package com.game.handler; import com.game.annotation.MessageAnnotation; import com.game.annotation.MethodAnnotation; import com.game.mahjonggame.message.BroadcastOwnDrawWinActionMessage; @MessageAnnotation public class TestHandler { @MethodAnnotation public void testHandler(BroadcastOwnDrawWinActionMessage message){ System.out.println("aaa-bbb"); } }怎样通过外部调用,去访问到@MessageAnnotation的方法呢? /** * 所有的类初始化一遍 , 把符合情况的保存下来 */ public RegisterMessage(URL url){ //把符合情况的拉下来 try { load(url , new ArrayList> classes) throws Exception { if ("jar".equals(url.getProtocol())) { findClassByJar(url.getFile(), classes); } else { File root = new File(url.getPath()); String prefix = root.getAbsolutePath(); findClassByCls(root, prefix, classes, PATH); for(Class class1:classes){ registerMessage(class1); } } } /** * 根据路径遍历获得JAR包下的所有.class文件 * * @param path * @return * @throws IOException * @throws ClassNotFoundException */ @SuppressWarnings("resource") private void findClassByJar(String path, List> list, String packages) { try { if (file.isDirectory()) { for (File f : file.listFiles()) findClassByCls(f, prefix, list, packages); } else { if (file.getName().endsWith("Handler.class")) { String parent = file.getParent(); String name = file.getName(); String packageName = null; if (parent.equals(prefix))// 如果是根路径 packageName = ""; else packageName = parent.substring(prefix.length() + 1) + File.separator; String className = name.substring(0, name.length() - 6); String classpath = (packageName + className).replace(File.separator, "."); list.add(Class.forName(packages + "." + classpath)); } } } catch (Exception e) { throw new RuntimeException("error in findClassByCls", e); } } @SuppressWarnings("unchecked") private void registerMessage(Class cls) throws Exception { MessageAnnotation handler = cls.getAnnotation(MessageAnnotation.class); if( null != handler ) { Method[] methods = cls.getDeclaredMethods(); for(Method m : methods){ MethodAnnotation action = m.getAnnotation(MethodAnnotation.class); if (action != null) { Class[] params = m.getParameterTypes(); if (params.length != 1) { //多个参数 //throw new IllegalArgumentException("参数只能有一个," + getPositionMsg(cls, m, params[0])); } Object msg = params[0].newInstance(); if (!(msg instanceof Message)) { /*throw new IllegalArgumentException( "参数必须是Message子类," + getPositionMsg(cls, m, params[0]));*/ } Message message = (Message) msg; int messageId = message.getId(); MessageSend msgSwap = messageSwaps.get(messageId); // 加载已有的HANDLER Object msgHandler = cls.newInstance(); MethodAccess methodAccess = MethodAccess.get(cls); msgSwap = new MessageSend(params[0], msgHandler, m, methodAccess); messageSwaps.put(messageId, msgSwap); msgSwap.setGm(action.isGm()); } } } } public MessageSend getMessageSend(int sendId){ return messageSwaps.get(sendId); }调用方法: 通过 methodAccess.invoke(handler, method.getName(), msg); 方法调用对应的类 package com.game.annotation; import java.lang.reflect.Method; import com.esotericsoftware.reflectasm.MethodAccess; import com.game.message.Message; public class MessageSend { private Class msgCls; private Object handler; private Method method; private MethodAccess methodAccess; private boolean isGm; public MessageSend(Class msgCls, Object handler, Method method, MethodAccess methodAccess) { this.msgCls = msgCls; this.method = method; this.handler = handler; this.methodAccess = methodAccess; } Class getMsgCls() { return msgCls; } public Method getMethod() { return method; } public Object getHandler() { return handler; } public boolean isGm() { return isGm; } void setGm(boolean gm) { isGm = gm; } public void action(Message msg) throws Exception { // method.invoke(handler, msg);//性能太差了 methodAccess.invoke(handler, method.getName(), msg); } public String getHandlerClassName() { return handler.getClass().getName() + ":" + method.getName(); }main 函数: public class TestMain { public static void main(String[] args) { RegisterMessage message = new RegisterMessage(TestMain.class.getResource("/com")); try { message.getMessageSend(254123).action( new BroadcastOwnDrawWinActionMessage()); } catch (Exception e) { e.printStackTrace(); }; }希望对你有用。 |
CopyRight 2018-2019 实验室设备网 版权所有 |