BeanFactory后处理器

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);
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值