电子说
想必@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条评论
快来发表一下你的评论吧 !