(转载请注明作者和出处‘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,世界变得更美好了。
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
Класс А400 и А500 — самые популярные виды арматуры, предназначенные для усиления бетонных конструкций, испытывающих высокие нагрузки. Такая арматура используется в фундаментных плитах, перекрытиях, колоннах и балках.
armatura-12.ru
Стальной двутавр — это фасонный металлопрокат с Н-образным сечением поперечного профиля. Он изготавливается горячекатаным способом из углеродистых или низколегированных сталей при температуре 1200°C по стандарту ГОСТ 8239-89 https://dvutavrmsk.ru
Класс Рђ400 Рё Рђ500 — наиболее востребованные типы арматуры, используемые для укрепления бетонных конструкций, которые подвергаются значительным нагрузкам. Ртот РІРёРґ арматуры применяется РІ фундаментных плитах, перекрытиях, колоннах Рё балках.
http://sarmatura-12.ru
Арматура диаметром 32 мм, изготовленная из стали марки А500С, является одним из самых востребованных видов металлопроката в строительстве. Она применяется при возведении фундаментов, армировании стен и перемычек. https://armatura32.ru
Арматура диаметром 32 мм, изготовленная из стали марки А500С, является одним из самых востребованных видов металлопроката в строительстве. Она применяется при возведении фундаментов, армировании стен и перемычек. https://armatura32.ru