//模拟实现ComponentScan
public class ComponentScanProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
SimpleMetadataReaderFactory readerFactory = new SimpleMetadataReaderFactory();
BeanNameGenerator nameGenerator = new AnnotationBeanNameGenerator();
//用AnnotationUtils查找此类上有没有ComponentScan注解
ComponentScan componentScan = AnnotationUtils.findAnnotation(Bean1.class, ComponentScan.class);
//不为空,有注解
if (componentScan != null) {
String[] packages = componentScan.basePackages();
for (String path : packages) {
//包名转换为路径名
//com.ghc.springlearning---->classpath*:com/ghc/springlearning/../*.class
String s = "classpath*:" + path.replace('.', '/') + "/**/*.class";
try {
Resource[] resources = new PathMatchingResourcePatternResolver().getResources(s);
for (Resource resource : resources) {
MetadataReader reader = readerFactory.getMetadataReader(resource);
AnnotationMetadata annotationMetadata = reader.getAnnotationMetadata();
if (annotationMetadata.hasAnnotation(Component.class.getName())
|| annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
.genericBeanDefinition(reader.getClassMetadata().getClassName())
.getBeanDefinition();
String beanName = nameGenerator.generateBeanName(beanDefinition, beanFactory);
beanFactory.registerBeanDefinition(beanName, beanDefinition);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
}
Bean1结构
@ComponentScan({"com.ghc.springlearning.MyPostProcessors.components"})
@Configuration
public class Bean1 {
}
包结构
测试:
public class Test {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("bean1",Bean1.class);
context.registerBean(ComponentScanProcessor.class);
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
System.out.println(name);
}
}
}