程序员社区

Spring 框架源码解读13


title: Spring 框架源码解读13
date: 2020/04/20 16:51


本节内容 & 思考题

@ComponentScan 注解

Spring 框架源码解读13插图
Spring 框架源码解读13插图1

点进去 parse 方法看看:

Spring 框架源码解读13插图2
Spring 框架源码解读13插图3

开始吧

@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;
}
赞(0) 打赏
未经允许不得转载:IDEA激活码 » Spring 框架源码解读13

一个分享Java & Python知识的社区