Spring-BeanFactory后处理器系列
文章目录
ComponentScanPostProcessor解析过程
1.查找目标类(Config)是否带有@ComponentScan注解,并获取对应扫描包下的各个类
2.查找扫描包下各个带有@Component及其衍生类的注解并对该类进行bean定义以及注册
一、查找@ComponentScan注解
查找Config(目标类)上是否有注解@ComponentScan, 若找到则返回注解对象componentScan
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
二、获取@ComponentScan注解扫描包位置
获得ComponentScan的basePackages(需要扫描的包名集合)
将包名转化为类路径(classpath*:com\javaweb\beanFactory\component\**\*.class)
通过ApplicationContext扩展getResources()方法获取类路径下多个class资源 (获得目标包下的class文件)
for (String p : componentScan.basePackages()) {
// 将包名称转化 -> 类路径 (字符串处理)
String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
// 读取类元信息
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
// 获取目标包下多个class文件集合
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
}
三、获取各个class文件所带有的component注解或衍生注解
CachingMetadataReaderFactory() 对象获取目标class类元信息
getAnnotationMetadata() 方法获取注解信息
hasAnnotation() hasMetaAnnotation() 验证当前目标class是否有@Component或其派生类信息
for (Resource resource : resources) {
// 读取类元信息
MetadataReader reader = factory.getMetadataReader(resource);
//System.out.println("类名:" + reader.getClassMetadata().getClassName());
// 获取注解信息
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
System.out.println("是否带有@Component注解:" + annotationMetadata.hasAnnotation(Component.class.getName()));
System.out.println("是否带有@Component派生注解:" + annotationMetadata.hasMetaAnnotation(Component.class.getName()));
}
四、注册bean定义
// 根据注解生成Bean名称
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
if (annotationMetadata.hasAnnotation(Component.class.getName()) || annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
// 创建BeanDefinition对象(目标class类的Bean定义)
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(reader.getClassMetadata().getClassName())
.getBeanDefinition();
// 注册Bean对象
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory;
String name = generator.generateBeanName(beanDefinition, beanFactory);
beanFactory.registerBeanDefinition(name, beanDefinition);
}
完整代码
将上述过程实现于BeanFactoryPostProcessor接口的postProcessBeanFactory方法中,从而完成自定义ComponentScanPostProcessor()类
package com.javaweb.beanFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.stereotype.Component;
import java.io.IOException;
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
@Override //context.refresh()
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
try {
ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
if (componentScan != null) {
for (String p : componentScan.basePackages()) {
// 将包名称转化 -> 类路径 (字符串处理)
String path = "classpath*:" + p.replace(".", "/") + "/**/*.class";
// 读取类元信息
CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
// 获取目标包下多个class文件集合
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
// 根据注解生成Bean名称
AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
for (Resource resource : resources) {
// 读取类元信息
MetadataReader reader = factory.getMetadataReader(resource);
// 获取注解信息
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
// 如果拥有@component注解或其派生注解
if (annotationMetadata.hasAnnotation(Component.class.getName()) || annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
// 创建BeanDefinition对象(目标class类的Bean定义)
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(reader.getClassMetadata().getClassName())
.getBeanDefinition();
// 注册Bean对象
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)configurableListableBeanFactory;
String name = generator.generateBeanName(beanDefinition, beanFactory);
beanFactory.registerBeanDefinition(name, beanDefinition);
}
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}