title: Spring 框架源码解读13
date: 2020/04/20 16:51
本节内容 & 思考题
@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;
}