电子说
想必@Component注解大家一直在使用,只要类上加上它,就可以被Spring容器管理,那大家有想过它是怎么实现的吗?本篇文章就带领到家揭秘。
用来标记的类是一个“组件”或者说是一个Bean,Spring会自动扫描标记@Component注解的类作为一个Spring Bean对象。
注解源码:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
String value() default "";
}
属性说明:
value: 自定义当前组件或者说bean的名称,可以不配置, 不配置的话默认为组件的首字母小写的类名。元注解说明:
@Indexed元注解在spring 5.0引入,用于项目编译打包时,会在自动生成META-INF/spring.components文件,简历索引,从而提高组件扫描效率,减少应用启动时间。Person类,被@Component注解修饰
Person类是否在扫描路径下


小结: 通过添加@Component能够将类转为Spring中的Bean对象,前提是能过够被扫描到。
阅读源码,我们查看@Component注解的源码,从中可以看到一个关键的类ClassPathBeanDefinitionScanner,我们可以从这个类下手,找到切入点。

分析ClassPathBeanDefinitionScanner类,找到核心方法doscan, 打个断点,了解整个调用链路。

具体分析结果如下:
SpringBoot应用启动会注册ConfigurationClassPostProcessor这个Bean,它实现了BeanDefinitionRegistryPostProcessor接口,而这个接口是Spring提供的一个扩展点,可以往BeanDefinition Registry中添加BeanDefintion。所以,只要能够扫描到@Component注解的类,并且把它注册到BeanDefinition Registry中即可。
ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry,查找@Component的类,并进行注册。
@Component的类的,核心方法就是ClassPathBeanDefinitionScanner#doScan。protected Set
ClassPathBeanDefinitionScanner#findCandidateComponents方法,找出候选的Bean Component。public Set
private Set
// 判断是否候选的Bean Component
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
// exclude过滤器,在exclude过滤其中的,会直接排除掉,返回false
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
// include过滤器, 这里会看到有AnnotationTypeFilter,注解类型过滤器
for (TypeFilter tf : this.includeFilters) {
// 调用AnnotationTypeFilter的match方法,来判断是否满足条件
if (tf.match(metadataReader, getMetadataReaderFactory())) {
// 下面在进行Condition的判断,就是类上的@Conditional,这里不是重点
return isConditionMatch(metadataReader);
}
}
return false;
}

而这个AnnotationTypeFilter默认是在构造函数中注册进去的。

小结:
@Component到Spring bean容器管理过程如下:
Component类型过滤器;.class文件,生成Resource对象;.class文件并注解归类,生成MetadataReader对象;@Component类;BeanDefinition对象;BeanDefinition注册到Spring容器。经过这篇文章文章,是不是对@Component的使用和实现原理一清二楚了呢,其实Spring中还有@Service、@Controller和@Repository等注解,他们和@Component有什么区别呢,你知道吗?
全部0条评论
快来发表一下你的评论吧 !