在nacos+config中,可以使用@NacosValue注解动态刷新private static类型的属性。但是private static类型的属性是属于类的,而不是属于对象的,因此不能使用普通的setter方法来动态刷新其值。
以下是一个示例代码,演示了如何使用@NacosValue注解来动态刷新private static类型的属性:
import comalibabanacosapiconfigannotationNacosValue;import orgspringframeworkstereotypeComponent;@Componentpublic class Config { @NacosValue(value = "${a}", autoRefreshed = true)
private static int a; public static int getA() { return a;
}
}
在上面的示例代码中,使用了@NacosValue注解来标记a属性。其中,value属性表示nacos配置中心中的配置项名称,${a}表示从配置中心获取名称为a的配置项的值,并将其赋值给a属性。autoRefreshed属性表示是否开启自动刷新功能,如果开启,则当配置中心中的配置项发生变化时,a属性的值也会相应地发生变化。
在使用private static类型的属性时,需要注意以下几点:
需要提供一个公共的getter方法,用于获取属性的值;
不能提供setter方法,因为private static类型的属性属于类,而不是对象,不能通过setter方法动态修改其值;
在使用@NacosValue注解时,需要将其标记在属性上,而不是标记在getter方法上;
在上述示例中,因为a属性是private static类型,因此不能提供setter方法,只能提供一个公共的getter方法getA()。当配置中心中的a配置项发生变化时,@NacosValue注解会自动更新a属性的值,因此可以通过ConfiggetA()方法获取最新的值。
需要注意的是,对于private static类型的属性,因为其属于类,因此在多线程环境下可能会存在线程安全问题。因此,应该尽量避免使用private static类型的属性,或者采取合适的线程安全措施。
Java注解(Annotation)就是一种java标注,并且能够携带数据, 是在JDK50被引入的。
Java的注解可以标注Java语言中的类、变量、方法、参数、包等等。
值得注意的是: 上面所说的Java注解只是一种标注,所以注解需要配合反射来使用才能发挥出强大作用。
注解的成员变量只支持 八种基本数据类型(byte、short、int、long、float、double、char、boolean)、String、Class、Enum、Annotation 。
还有的就是,所有的注解都是Annotation接口的实现类,可以把Annotation接口看成是所有注解的超类 。
上面就是定义了一个可以标注在类或者注解以及方法上的,保留到运行期的注解。 但是也仅仅是定义了一个注解而已,一个注解要发挥它自己的作用,还需要反射的配合。
反射是java中的一种机制,通过这种机制我们能够在运行时获取到一个类的一切信息(继承的类、实现的接口、属性、方法等), 以及注解信息和注解所携带的数据 。
通过获取到的类信息,我们可以构造一个新的对象、获取到某个对象的属性值、执行某个对象的方法等。
定义value注解
定义pojo User类
测试并使用注解
众所周知, spring 从 25 版本以后开始支持使用注解代替繁琐的 xml 配置,到了 springboot 更是全面拥抱了注解式配置。平时在使用的时候,点开一些常见的等注解,会发现往往在一个注解上总会出现一些其他的注解,比如 @Service :
大部分情况下,我们可以将 @Service 注解等同于 @Component 注解使用,则是因为 spring 基于其 JDK 对 元注解的机制 进行了扩展。
在 java 中,元注解是指可以注解在其他注解上的注解,spring 中通过对这个机制进行了扩展,实现了一些原生 JDK 不支持的功能,比如允许在注解中让两个属性互为别名,或者将一个带有元注解的子注解直接作为元注解看待,或者在这个基础上,通过 @AliasFor 或者同名策略让子注解的值覆盖元注解的值。
本文将基于 spring 源码 52x 分支,解析 spring 如何实现这套功能的。
这是系列的第三篇文章,将详细介绍 Spring 是如何在经过搜索与属性映射后,将处理后的注解合成为合并注解的。
相关文章:
我们在前文了解用于搜索注解的合并注解聚合 MergedAnnotations 与用于完成注解属性映射的 AnnotationTypeMappings 和 AnnotationTypeMapping ,现在我们需要知道在 MergedAnnotations 这个容器中, AnnotationTypeMappings 和 AnnotationTypeMapping 是如何转为一个我们所需要的合并注解 MergedAnnotation 的。
与前文一样,我们以 AnnotatedElementUtilsfindMergedAnnotations 方法作为入口:
我们在上文顺着 MergedAnnotationsget 一路找到 TypeMappedAnnotationsMergedAnnotationFinder 的 process 方法,在这里我们目睹了一个普通的注解的元注解被解析为 AnnotationTypeMappings 与 AnnotationTypeMapping 的过程:
该方法是 AnnotationTypeMapping 转为 MergedAnnotation 的关键。
TypeMappedAnnotation 是 MergedAnnotation 一个通用实现,在大部分情况下,我们所说的合并注解其实指的就是这个类。
通过它的构造方法我们得以了解其创建过程:
可以看得出, TypeMappedAnnotation 基本可以认为是 AnnotationTypeMapping 的包装类,它以一个 AnnotationTypeMapping 实例作为数据源,从而提供一些关于映射后的属性的相关功能。
回到 AnnotatedElementUtilsfindMergedAnnotations ,我们可以看到,在通过 MergedAnnotations 获得了一个 MergedAnnotation 对象——实际上是 TypeMappedAnnotation 对象——之后,又调用了 MergedAnnotationsynthesize 方法,将 MergedAnnotation 转成了一个调用方指定类型的注解对象。
该方法先调用了 AbstractMergedAnnotation 的 synthesize 方法:
随后再调用了实现类 TypeMappedAnnotation 的 synthesize 方法:
继续点开 createSynthesized :
而 SynthesizedMergedAnnotationInvocationHandler 是一个用于 JDK 动态代理的 InvocationHandler ,我们不需要完全站看,仅需看看它的构造函数与 InvocationHandlerinvoke 就能明白它的运作机制了:
至此,合并注解的合成机制已经很明确了:
承接上文,当我们使用 MergedAnnotationsynthesize 方法时,我们可能会得到两种对象:
而通过注解代理对象取值时,这些方法会被代理到 SynthesizedMergedAnnotationInvocationHandler 中存放的 MergedAnnotation 对象上,从而让这个代理对象通过原始注解的属性,获得与原始注解不一样的属性值。
当我们调用代理对象的属性值时,它会在 SynthesizedMergedAnnotationInvocationHandler 中,通过 invoke 代理到对应的方法上:
这里我们代理对象是如何获取注解属性值的:
这里的 MergedAnnotationgetValue 最终在经过多次跳转后,调到 TypeMappedAnnotationgetAttributeValue 上:
而这边的 getValue 方法就是真正要获取属性值的地方。
这一步有点复杂,主要是根据不同的情况,通过 AnnotationTypeMapping 中的几个属性映射数组,包括 aliasMappings 、 conventionMappings , annotationValueMappings 与 annotationValueSource 来确定最终用于取值的 AnnotationTypeMapping 对象与调用的方法在 AttributeMethods 中的下标:
至此,获取属性值的方法流程也走完了。
在这一章,我们了解了当通过 MergedAnnotations 获得注解并解析得到 AnnotationTypeMapping 后, AnnotationTypeMapping 是如何再转为我们所需的 MergedAnnotation ,以及在此之后, MergedAnnotation 又是如何生成我们最终所需要的代理注解的。
简而言之,当解析注解的元注解获得所需的 AnnotationTypeMapping 后, MergedAnnotation 会判断 AnnotationTypeMapping 是否发生过属性映射,如果没有则返回该映射对象对应的原始注解,否则就通过 SynthesizedMergedAnnotationInvocationHandler 生成一个对应类型的 JDK 动态代理对象。
当我们通过代理对象去调用注解的方法,获取注解的属性的时候, SynthesizedMergedAnnotationInvocationHandler 会把方法代理到对应的内部方法中,而获取属性时,还会通过 MergedAnnotationgetValue ,最终绕到 AnnotationTypeMapping 中获取被映射后的属性值。
以上就是关于nacos+config如何动态刷新private+static+integer+a=9全部的内容,包括:nacos+config如何动态刷新private+static+integer+a=9、通过注解和反射实现一个简单的@Value注解、深入理解Spring注解机制:合并注解的合成等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)