Spring底层原理(四)

Spring底层原理(四)

本章内容

模拟实现Spring中的几个常见BeanFactory后置处理器

常见的BeanFactory后置处理器
java 复制代码
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("config",Config.class);
context.registerBean(ConfigurationClassPostProcessor.class);//解析@ComponentScan @Bean @Import @ImportResource
ontext.registerBean(MapperScannerConfigurer.class,bd->{
	bd.getPropertyValues().add("basePackage","com.vmware.mapper");
});
//初始化容器
context.refresh();
for (String name : context.getBeanDefinitionNames()) {
    System.out.println(name);
}
context.close();
  • ConfigurationClassPostProcessor:解析@ComponentScan @Bean @Import @ImportResource
  • MapperScannerConfigurer:解析@Mapper
模拟实现组件扫描
  • 创建一个BeanFactoryPostProcessor的实现类
java 复制代码
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        ComponentScan componentScan = AnnotationUtils.findAnnotation(Config.class, ComponentScan.class);
        try {
            if (componentScan != null) {
                for (String basePackage : componentScan.basePackages()) {
                    System.out.println(basePackage);
                    String path = "classpath*:" + basePackage.replace(".", "/") + "/**/*.class";
                    System.out.println(path);
                    //用于获取元数据的工具类
                    CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
                    //用于生成bean名称的工具
                    AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
                    Resource[] resources = new PathMatchingResourcePatternResolver().getResources(path);
                    for (Resource resource : resources) {
                        MetadataReader metadataReader = factory.getMetadataReader(resource);//根据resource获取元数据读取器
                        AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
//                    ClassMetadata classMetadata = metadataReader.getClassMetadata();
//                    System.out.println("类名:" + classMetadata.getClassName());
//                    //判读是否有注解@Component
//                    boolean hasComponent = metadataReader.getAnnotationMetadata().hasAnnotation(Component.class.getName());
//                    System.out.println("包含注解Component:" + hasComponent);
//                    boolean hasMetaAnnotation = metadataReader.getAnnotationMetadata().hasMetaAnnotation(Component.class.getName());
//                    System.out.println("元注解中包含Component:"+hasMetaAnnotation);
                        if (annotationMetadata.hasAnnotation(Component.class.getName()) || annotationMetadata.hasMetaAnnotation(Component.class.getName())) {
                            //构建beanDefinition对象
                            AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(metadataReader.getClassMetadata().getClassName()).getBeanDefinition();
                            if (configurableListableBeanFactory instanceof DefaultListableBeanFactory) {
                                //获取容器
                                DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
                                //生成bean name
                                String name = generator.generateBeanName(bd, beanFactory);
                                //注册bean
                                beanFactory.registerBeanDefinition(name, bd);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 注册该后置处理器

    java 复制代码
    context.registerBean(ComponentScanPostProcessor.class);
模拟实现@Bean
java 复制代码
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        try {
            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
            MetadataReader reader = factory.getMetadataReader(new ClassPathResource("com/vmware/a5/Config.class"));
            Set<MethodMetadata> methods = reader.getAnnotationMetadata().getAnnotatedMethods(Bean.class.getName());
            for (MethodMetadata method : methods) {
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
                //Bean的名称由方法名生成,除此之外还需要一个工厂Bean对象
                builder.setFactoryMethodOnBean(method.getMethodName(), "config");
                builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                AbstractBeanDefinition bd = builder.getBeanDefinition();
                if (configurableListableBeanFactory instanceof DefaultListableBeanFactory) {
                    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
                    beanFactory.registerBeanDefinition(method.getMethodName(), bd);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
模拟实现Mapper扫描
java 复制代码
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanFactory) throws BeansException {
        try {
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources("classpath:com/vmware/a5/mapper/**/*.class");
            AnnotationBeanNameGenerator generator = new AnnotationBeanNameGenerator();
            CachingMetadataReaderFactory factory = new CachingMetadataReaderFactory();
            for (Resource resource : resources) {
                MetadataReader reader = factory.getMetadataReader(resource);
                //获取类元数据
                ClassMetadata classMetadata = reader.getClassMetadata();
                //过滤接口类型
                if (classMetadata.isInterface()){
                    AbstractBeanDefinition bd = BeanDefinitionBuilder.genericBeanDefinition(MapperFactoryBean.class)
                            .addConstructorArgValue(classMetadata.getClassName())//构造方法需要对应的接口字节码
                            .setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE)//需要对MapperFactory进行注入
                            .getBeanDefinition();
                    //根据接口名称重新生成一个bean,仅用于生成mapper的名称,否则所有名称都是MapperFactoryBean
                    AbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();
                    String name = generator.generateBeanName(bd2, beanFactory);
                    beanFactory.registerBeanDefinition(name,bd);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }
}
  • 将Mapper封装成MapperFactoryBean类型,然后注册到容器中
相关推荐
能摆一天是一天6 分钟前
JAVA stream().flatMap()
java·windows
颜如玉1 小时前
🤲🏻🤲🏻🤲🏻临时重定向一定要能重定向🤲🏻🤲🏻🤲🏻
java·http·源码
程序员的世界你不懂2 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
星空寻流年2 小时前
设计模式第一章(建造者模式)
java·设计模式·建造者模式
gb42152873 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
曾经的三心草3 小时前
Python2-工具安装使用-anaconda-jupyter-PyCharm-Matplotlib
android·java·服务器
Metaphor6923 小时前
Java 高效处理 Word 文档:查找并替换文本的全面指南
java·经验分享·word
ChinaRainbowSea3 小时前
7. LangChain4j + 记忆缓存详细说明
java·数据库·redis·后端·缓存·langchain·ai编程
stormsha3 小时前
飞算JavaAI炫技赛电商系统商品管理模块的架构设计与实现
java·架构·鸿蒙系统
minh_coo4 小时前
Spring框架事件驱动架构核心注解之@EventListener
java·后端·spring·架构·intellij-idea