【p3】Java自定义注解

(转载请注明作者和出处‘https://fourthringroad.com/’,请勿用于任何商业用途)

我在犹豫是否要给注解单独写一章,毕竟不是项目重点;但是想了想,简单梳理一下吧,当是温故知新了。

注解是简化代码,提高可读性很好的途径,能够以更好隐藏底层逻辑,实现不同模块的低耦合;对于用户来讲,如果你的服务以注解的方式提供支持,显然能够降低onboard的代码量以及对于用户服务的侵入性。

关于注解的一些基础知识,简单列举一下:

  • 说白了注解的本质就是给代码对象(类,方法,参数。。。等)加上一些额外信息,这些额外信息会被一些处理器在处理这些代码对象时使用。这里所谓的额外信息,除了注解本身之外,还有注解提供的配置参数,后者类型包括:基本数据类型,其他注解,String,enum和它们的数组等。
  • 元注解用于修饰其他注解,常用的有:
    • @Target:定义注解修饰的对象是什么,包括TYPE, x.FIELD, x.METHOD, x.CONSTRUCTOR, x.PARAMETER 等等。
    • @Retention: 定义注解的生命周期,包括SOURCE, x.CLASS, x.RUNTIME
    • @Inherited: 注解关系是否具有继承性,即子类是否继承父类的接口
  • 注解本身不支持继承(extends),但是所有的注解在编译后会继承lang.annotaion.Annotation接口。所以如何获取注解提供的额外信息?显然答案是反射;简单的反射API如下
    • 判断某个类,属性,方法时候有某个注解,例如getClass().isAnnorationPresent(XxAnnotation);
    • 读取注解:XxAnnotationxxAnnotation = xx.getClass().getAnnoration(XxAnnotation.class);进一步可以通过xxAnnoration实例获得注解的配置参数
    • 更多的方法可以参考java.lang.reflect下的接口AnnotatedElement

OK,上面是一些注解基础知识,如果我们想像在文章p1中讲的那样,自定义一个配置解析的注解,需要怎么做?

@配置专用Annotation(配置ID=“xx” 解析格式=“json/xml/yml...”)
@Component
ConfigBean {
    String foo;
    Long bar;
}

首先确定需要什么元注解:

  • 我们需要注解在运行时能够使用,那么就需要定义元注解@Retention,并执行RetentionPolicy为RUNTIME
  • 我们需要将配置文件映射到ConfigBean,所以注解使用的对象是类,即ElementType=TYPE

然后确定我们的注解需要提供什么信息:

应用需要跟配置中心服务进行交互,所以需要配置中心服务端地址,同时还需要应用名称和配置的ID来定位一个具体的配置文件;如何解析一个配置文件(xml,json,yml…);配置中心服务端地址和应用名称是公用的,所以可以放置到公共的配置文件中;在注解层面需要提供的就是配置的ID和解析方式。

最后我们需要实现处理器

在运行时,如何将带有自定义注解的ConfigBean与相应配置文件同步?显然我们需要自定义一个处理器,并且在Bean的合适的生命周期节点执行这个处理器的逻辑,这个处理器的逻辑为:解析注解配置,获得需要同步的配置信息以及解析方式,向配置中心发起获取配置信息,在拿到配置后,用匹配的解析器解析配置文件并赋予ConfigBean。

代码架构如下:

//注解本身
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ConfigAnnotation {

    //配置的ID
    String value();

    enum Format {XML, JSON, YML, PROPERTIES}

    //配置文件的类型
    Format format() default Format.PROPERTIES;
}
//在实体类使用注解
@ConfigAnnotation(value = "xx.json", format = ConfigAnnotation.Format.JSON)
public class ConfigBean {

    private String foo;

    private Integer bar;
}
//注解处理器的逻辑
public class Processor {

    private ConfigService configService;

    private Resolver resolver;

    public Object getInstance(String reference) throws ClassNotFoundException {
        final Class<?> aClass = Class.forName(reference);

        if (aClass.isAnnotationPresent(ConfigAnnotation.class)) {
            ConfigAnnotation configAnnotation = aClass.getAnnotation(ConfigAnnotation.class);

            //读取配置属性
            final String configID = configAnnotation.value();
            final ConfigAnnotation.Format format = configAnnotation.format();

            //获取配置
            final String config = this.configService.getConfig(configID);

            //解析配置
            return this.resolver.resolve(config, aClass);
        }

        throw new IllegalStateException("处理失败");
    }
}

作为服务的提供方,处理器的逻辑被我完全隐藏了起来,用户只需要简单的利用我定义的注解进行服务接入,OK,世界变得更美好了。

此条目发表在spring相关分类目录。将固定链接加入收藏夹。

【p3】Java自定义注解》有6条回应

  1. brotapova说:

    priligy india In this open label study using a noninferiority design, patients on metformin were randomized to have rosiglitazone or sulfonylurea added; those on sulfonylurea were randomly assigned to the addition of either rosiglitazone or metformin

  2. MiguelPah说:

    Класс А400 и А500 — самые популярные виды арматуры, предназначенные для усиления бетонных конструкций, испытывающих высокие нагрузки. Такая арматура используется в фундаментных плитах, перекрытиях, колоннах и балках.

    armatura-12.ru

  3. Robertanoke说:

    Стальной двутавр — это фасонный металлопрокат с Н-образным сечением поперечного профиля. Он изготавливается горячекатаным способом из углеродистых или низколегированных сталей при температуре 1200°C по стандарту ГОСТ 8239-89 https://dvutavrmsk.ru

  4. MiguelPah说:

    Класс А400 и А500 — наиболее востребованные типы арматуры, используемые для укрепления бетонных конструкций, которые подвергаются значительным нагрузкам. Этот вид арматуры применяется в фундаментных плитах, перекрытиях, колоннах и балках.

    http://sarmatura-12.ru

  5. Robertanoke说:

    Арматура диаметром 32 мм, изготовленная из стали марки А500С, является одним из самых востребованных видов металлопроката в строительстве. Она применяется при возведении фундаментов, армировании стен и перемычек. https://armatura32.ru

  6. Robertanoke说:

    Арматура диаметром 32 мм, изготовленная из стали марки А500С, является одним из самых востребованных видов металлопроката в строительстве. Она применяется при возведении фундаментов, армировании стен и перемычек. https://armatura32.ru

发表评论

您的电子邮箱地址不会被公开。