三万字盘点Spring/Boot的那些常用扩展点( 二 )


User user = .(User.class);
.out.("获取到的Bean为"+ user +",属性值为:"+ user.());
}
}
测试结果:
1
获取到的Bean为com....User@,属性值为:三友的java日记
从结果可以看出,每个生成的Bean在执行到某个阶段的时候,都会回调r,然后r就会判断当前创建的Bean的类型,如果是User类型,那么就会将的属性设置为 ”三友的java日记“ 。
内置的
这里我列举了常见的一些的实现以及它们的作用
作用
处理@、@Value注解
处理@、@、@注解
处理一些注解或者是AOP切面的动态代理
处理Aware接口注入的
处理@Async注解
处理@注解
通过列举的这些的实现可以看出,Bean的很多注解的处理都是依靠及其子类的实现来完成的,这也回答了上一小节的疑问,处理@、@、@注解是如何起作用的,其实就是通过,在Bean的不同阶段来调用对应的方法起作用的 。
在Dubbo中的使用
在Dubbo中可以通过@(@)来引用生产者提供的接口,这个注解的处理也是依靠,也就是的扩展来实现的 。
1
2
3
4
5
or
, ssor {
// 忽略
}
当Bean在创建的某一阶段,走到了这个类,就会根据反射找出这个类有没有@(@)注解,有的话就构建一个动态搭理注入就可以了 。
在 Bean的扩展中扮演着重要的角色,是 Bean生命周期中很重要的一部分 。正是因为有了,你就可以在Bean创建过程中的任意一个阶段扩展自己想要的东西 。ssor
通过上面一节我们知道是对Bean的处理,那么ssor很容易就猜到是对,也就是容器的处理 。
举个例子,如果我们想禁止循环依赖,那么就可以这么写 。
1
2
3
4
5
6
7
8
9
{
@
( ) {
// 禁止循环依赖
(() ).(false);
}
}
后面只需要将注入到容器中就会生效 。
ssor是可以对容器做处理的,方法的入参就是的容器,通过这个接口,就对容器进行为所欲为的操作 。SPI机制
SPI全称为 (),是一种动态替换发现的机制,一种解耦非常优秀的思想,SPI可以很灵活的让接口和实现分离,让api提供者只提供接口,第三方来实现,然后可以使用配置文件的方式来实现替换或者扩展,在框架中比较常见,提高框架的可扩展性 。
JDK有内置的SPI机制的实现,Dubbo也有自己的SPI机制的实现,但是这里我们都不讲 。。
但是,我之前写过相关的文章,文章的前半部分有对比三者的区别,有需要的小伙伴可以关注微信公众号 三友的java日记 回复 dubbo spi 即可获得 。
这里我们着重讲一下的SPI机制的实现r 。
r
的SPI机制规定,配置文件必须在路径下的META-INF文件夹内,文件名必须为.,文件内容为键值对,一个键可以有多个值,只需要用逗号分割就行,同时键值都需要是类的全限定名 。但是键和值可以没有任何关系,当然想有也可以有 。
show me the code
这里我自定义一个类,ation作为键,值就是User
1
2
{
}
spring.factories文件
1
com....spi.ation=com....User
然后放在META-INF底下
测试:
1
2
3
4
5
6
7
8
on {
([] args) {
List= r.(ation.class, ation.class.());
.(.out::);
}
}
结果:
1
com....User
可以看出,通过r的确可以从.文件中拿到ation键对应的值 。
到这你可能说会,这SPI机制也没啥用啊 。的确,我这个例子比较简单,拿到就是遍历,但是在中,如果在加载类的话使用SPI机制,那我们就可以扩展,接着往下看 。