title: Spring 框架源碼解讀13
date: 2020/04/20 16:51
本節(jié)內容 & 思考題
@ComponentScan 注解
點進去 parse 方法看看:
開始吧
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
/**
* 掃描的包
*/
String[] value();
}
private void processConfigurationClass(BeanDefinitionRegistry registry, BeanDefinition classBeanDefinition, Class<?> clazz) {
...
// 4长踊、處理 @ComponentScan 注解
ComponentScan componentScan = AnnotationUtil.getAnnotation(clazz, ComponentScan.class);
if (ObjectUtil.isNotEmpty(componentScan) && ObjectUtil.isNotEmpty(componentScan.value())) {
// 掃描包并加入 bdMap 中
List<BeanDefinition> beanDefinitions = this.processComponentScan(registry, componentScan.value());
// 處理掃描到的類上包含 @Configuration 的,對他進行解析
for (BeanDefinition beanDefinition : beanDefinitions) {
// 找到類上攜帶 @Configuration 的
Class<?> childClazz = ReflectUtils.getType(beanDefinition.getClassName());
Configuration configuration = AnnotationUtil.getAnnotation(childClazz, Configuration.class);
if (ObjectUtil.isNotEmpty(configuration)) {
// 處理 @Configuration 標注的類
this.processConfigurationClass(registry, beanDefinition, childClazz);
}
}
}
...
}
private List<BeanDefinition> processComponentScan(BeanDefinitionRegistry registry, String[] basePackages) {
List<BeanDefinition> beanDefinitions = new ArrayList<>();
for (String basePackage : basePackages) {
Set<Class<?>> classes = ClassUtil.scanPackage(basePackage);
for (Class<?> clazz : classes) {
// 判斷是否具有 @Component 注解嚼松,并且本身不是注解
Component component = AnnotationUtil.getAnnotation(clazz, Component.class);
if (ObjectUtil.isNotNull(component) && !clazz.isAnnotation()) {
DefaultBeanDefinition bd = new DefaultBeanDefinition();
String beanName = StrUtil.isNotBlank(component.value()) ? component.value() : StrUtil.lowerFirst(clazz.getSimpleName());
bd.setName(beanName);
bd.setClassName(clazz.getName());
registry.registerBeanDefinition(beanName, bd);
beanDefinitions.add(bd);
}
}
}
return beanDefinitions;
}