[杂记]自定义注解以及反射的应用

序:对于注解的认知是从spring开始的,不管是aop还是ioc,对于其概念是比较清楚的,但真正的实现却没有一个比较好的认知,前段时间看了下《从零开始写web框架》,但当时看的比较仓促,再说因为时间的原因,并没有细揪很多东西,这两天研究了下公司一个系统的代码,突然间对于这块有了比较好的理解,故做潦草记录。

项目使用自定义注解和反射主要是为了在webSocket请求发过来的时候,通过请求中的参数定位到类和方法,然后去执行具体的业务逻辑,具体整个流程如下。

1、自定义注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface SocketCommand {    /**     * 请求的命令号     * @return     */    short cmd();}
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface SocketModule {

/**     * 请求的模块号     * @return     */   short module();}第一个注解配置在方法上,第二个注解配置到类上。2、利用BeanPostProcessor类中的postProcessAfterInitialization方法,在实例化类之后开始做注解扫描。
@Componentpublic class HandlerScanner implements BeanPostProcessor{    private Logger logger = Logger.getLogger(HandlerScanner.class);    @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){                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;                       }                       short module = socketModule.module();                       short cmd = socketCommand.cmd();                       try {                           if (InvokerHoler.getInvoker(module,cmd)==null){                               InvokerHoler.addInvoker(module,cmd, Invoker.valueOf(method,bean));--将符合条件的加入到map中                           }else {                               logger.error("重复命令:"+"module:"+module+" "+"cmd: "+cmd);                           }                       } catch (Exception e) {                           logger.error("获取失败: "+e.getMessage());                       }                   }                }            }        }        return bean;    }}附录InvokerHoler:
public class InvokerHoler {

/**     * 命令调用器     */    private static Map<Short,Map<Short,Invoker>> invokers = new HashMap<Short, Map<Short, Invoker>>();

/**     * 添加命令调用     * @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<Short, Invoker>();            invokers.put(module,map);        }        map.put(cmd,invoker);    }

/**     * 获取命令调用     * @param module     * @param cmd     * @return     * @throws Exception     */    public static Invoker getInvoker(Short module,Short cmd)throws Exception{        Invoker invoker = null;        Map<Short,Invoker> map = invokers.get(module);        if(map!=null){            invoker = map.get(cmd);        }        return invoker;    }}附录Invoker:
public class Invoker {

private Logger logger = Logger.getLogger(Invoker.class);

/**     * 方法     */    private Method method;

/**     * 目标对象     */    private Object target;

/**     * 获取实体类     * @param method     * @param target     * @return     */    public static Invoker valueOf(Method method,Object target){        Invoker invoker = new Invoker();        invoker.setMethod(method);        invoker.setTarget(target);        return invoker;    }

public Object invoke(Object... paramValues){        try {            return method.invoke(target,paramValues);        } catch (IllegalAccessException e) {            logger.error(e.getMessage());        } catch (InvocationTargetException e) {            logger.error(e.getMessage());        }        return null;    }    public void setMethod(Method method) {        this.method = method;    }

public void setTarget(Object target) {        this.target = target;    }

public Method getMethod() {        return method;    }

public Object getTarget() {        return target;    }}3、第二步的操作相当于已经把所有自定义注解表标识的类放入到了map中,map的结构为Map<Short,Map<Short,Invoker>>,此时在webscoket连链接中获取传入的参数,并寻找指定的方法。
@Overrideprotected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame frame) throws Exception {   SessionImpl session = new SessionImpl(ctx.channel());   Channel channel = ctx.channel();   String request = frame.text();   logger.debug("收到信息:"+request);   WebSocketRequest webSocketRequest = JsonUtils.readValue(request, WebSocketRequest.class);   checkParameters(webSocketRequest);   Invoker invoker = InvokerHoler.getInvoker(webSocketRequest.getModule(), webSocketRequest.getCmd());--获取执行方法   if (invoker == null){      throw new Exception("没有找到相应的执行器");   }   invoker.invoke(session,webSocketRequest);执行方法

附录MsgHandler:
@SocketModule(module = 1)public interface MsgHandler {

@SocketCommand(cmd = 1)    void sendMessage(Session session,Object message) throws Exception;}链接数据: ‘{"version":"1","module":1,"cmd":1,"data":"‘+message+‘"}‘;通过Moudlue和cmd定位到1:1方法,寻找其实现类进行执行。
时间: 2024-08-01 08:40:43

[杂记]自定义注解以及反射的应用的相关文章

java自定义注解与反射

java注解与反射一.Java中提供了四种元注解,专门负责注解其他的注解,分别如下 1.@Retention元注解,表示需要在什么级别保存该注释信息(生命周期).可选的RetentionPoicy参数包括: RetentionPolicy.SOURCE: 停留在java源文件,编译器被丢掉 RetentionPolicy.CLASS:停留在class文件中,但会被VM丢弃(默认) RetentionPolicy.RUNTIME:内存中的字节码,VM将在运行时也保留注解,因此可以通过反射机制读取注

使用自定义注解和反射 ,自动生成查询语句

1.自定义表名注解 package com.lf.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; //自定义表名注解 @Target(ElementType.TYPE) @Retention(Reten

反射+自定义注解---实现Excel数据列属性和JavaBean属性的自动映射

简单粗暴,直奔主题.   需求:通过自定义注解和反射技术,将Excel文件中的数据自动映射到pojo类中,最终返回一个List<pojo>集合? 今天我只是通过一位使用者的身份来给各位分享一套超级可以的POI"工具",这套工具我只是第一个使用者,创作者是我的朋友,他喜好钻研底层和算法,擅长计算机软硬件,在我心里他一直是神一样的存在,每天晚上10点后我才能看到他,因为他每天需要加班,需要有更多时间能够学习,唉,这种毅力和耐力,我是真的羡慕,因为我也一直在努力,能够得到更多的东

使用Java反射(Reflect)、自定义注解(Customer Annotation)生成简单SQL语句

这次给大家介绍一下在Java开发过程中 使用自定义注解开发:主要知识点:            1.反射            主要用于提取注解信息            2.自定义异常  主要是为了自己自定义一个异常信息            3.自定义注解  本次重点 学会如何自定义注解以及如何使用反射提取注解信息运用到实际开发下图表示在Java中注解的含义以及注解的分类和如何解析注解 通常我们使用自定义注解一般使用4中元注解即:@Target@Retention@Documented@In

Java自定义注解反射校验数据

package com.annotations.ecargo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUN

Java注解教程:自定义注解示例,利用反射进行解析

Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入的,目前已被广泛应用于各种Java框架,如Hibernate,Jersey,Spring.注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效. 在注解诞生之前,程序的元数据存在的形式仅限于java注释或javadoc,但注解可以提供更多

如何自定义注解Annotation,并利用反射进行解析

Java注解能够提供代码的相关信息,同时对于所注解的代码结构又没有直接影响.在这篇教程中,我们将学习Java注解,如何编写自定义注解,注解的使用,以及如何使用反射解析注解. 注解是Java 1.5引入的,目前已被广泛应用于各种Java框架,如Hibernate,Jersey,Spring.注解相当于是一种嵌入在程序中的元数据,可以使用注解解析工具或编译器对其进行解析,也可以指定注解在编译期或运行期有效. 在注解诞生之前,程序的元数据存在的形式仅限于java注释或javadoc,但注解可以提供更多

Java反射与自定义注解

反射,在Java常用框架中屡见不鲜.它存在于java.lang.reflact包中,就我的认识,它可以拿到类的字段和方法,及构造方法,还可以生成对象实例等.对深入的机制我暂时还不了解,本篇文章着重在使用方面,并附上一个本人应用到项目中的案例. 基础姿势 拿到类,反射是以类为基础的基础,首先拿到项目中的类,既可以这样拿 Class<?> clazz = Class.forName(类路径); 也可以这样拿 Class<?> clazz = 类名.getClass(); 在一般意义的J

Java的自定义注解及通过反射获取注解

一.注解基本知识 1.元注解:@Retention @Target @Document @Inherited 2.Annotation型定义为@interface, 所有的Annotation会自动继承java.lang.Annotation这一接口,并且不能再去继承别的类或是接口. 3.参数成员只能用public或默认(default)这两个访问权修饰 4.参数成员只能用基本类型byte,short,char,int,long,float,double,boolean八种基本数据类型和Stri