通过自定义枚举 实现监听与触发(监听器Listener)@Target @Retention

2023-12-27 21:16:23

1.首先我们创建两个自定义注解

@CustomAnnotationListener
@CustomAnnotation
下面创建两个注解类
![](https://img-blog.csdnimg.cn/direct/c6e8949e0bec4f8f883844ccd81cca70.png在这里插入图片描述

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotationListener {

}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CustomAnnotation {
ProcessingType value();
}
@Target 与 @Retention 注解讲解
@Target(ElementType.TYPE)——接口、类、枚举、注解
@Target(ElementType.FIELD)——字段、枚举的常量
@Target(ElementType.METHOD)——方法
@Target(ElementType.PARAMETER)——方法参数
@Target(ElementType.CONSTRUCTOR) ——构造函数
@Target(ElementType.LOCAL_VARIABLE)——局部变量
@Target(ElementType.ANNOTATION_TYPE)——注解
@Target(ElementType.PACKAGE)——包
RetentionPolicy.SOURCE:这种类型的Annotations只在源代码级别保留,编译时就会被忽略,在class字节码文件中不包含。
RetentionPolicy.CLASS:这种类型的Annotations编译时被保留,默认的保留策略,在class文件中存在,但JVM将会忽略,运行时无法获得。
RetentionPolicy.RUNTIME:这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用反射机制的代码所读取和使用。
@Document:说明该注解将被包含在javadoc中
@Inherited:说明子类可以继承父类中的该注解

2.编写监听注解方法

@CustomAnnotationListener
public class ThreadHandle {
@CustomAnnotation(自定义一个枚举类即可)
public void handle(BaseParamBean paramBean) {
//这里面处理我们监听后需要处理的 例如英雄升级 我们处理英雄升级所带来的改变
}
}

3.选择文件扫描相关的自定义注解

public class HandleRegister {
private static volatile HandleRegister instance;
private Map<Integer, Method> handleMap = new ConcurrentHashMap<>();
private Map<Integer, Object> handleObjectMap = new ConcurrentHashMap<>();

private HandleRegister() {}
public static HandleRegister getInstance() {
    if(instance == null) {
        synchronized (ConfigManager.class) {
            if(instance == null) {
                HandleRegister inst = new HandleRegister();
                inst.register();
                instance = inst;
            }
        }
    }
    return instance;
}

private void initialize(String searchPackage) {
    Set<Class<?>> controllers = ClassScanner.listClassesWithAnnotation(searchPackage,
            CustomAnnotationListener.class);
    for (Class<?> controller : controllers) {
        try {
            Object handler = controller.newInstance();
            Method[] methods = controller.getMethods();
            for (Method method : methods) {
                CustomAnnotation ca = method.getAnnotation(CustomAnnotation.class);
                if(null != ca){
                    int key = ca.value().ordinal();
                    handleMap.put(key, method);
                    handleObjectMap.put(key,handler);
                }
            }
        } catch (Exception e) {
            Log.serverlog.error("", e);
        }
    }
}

public Object getObject(int type){
    return handleObjectMap.get(type);
}



/**
 * 注册handle
 */
private void register() {
    try {
        initialize("枚举类使用在什么位置的路径");
    }catch (Exception e){
        Log.serverlog.error("", e);
    }
}

/**
 * 获取对应的handle
 * @param type
 * @return
 */
public Method getMethod(int type){
    return handleMap.get(type);
}

4.通过将对象放入相关线程种 最后调用invoke触发 第2步骤中的方法即可

我们通过 自定义枚举 类似于监听枚举1 之后触发调用的就是枚举1

Method method = HandleRegister.getInstance().getMethod(枚举id);
method.invoke(HandleRegister.getInstance().getObject(枚举id),具体的对象);

文章来源:https://blog.csdn.net/weixin_43801300/article/details/135252202
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。