Spring底层原理(四)

Spring底层原理(四)

本章内容

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

常见的BeanFactory后置处理器
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的实现类
public class ComponentScanPostProcessor implements BeanFactoryPostProcessor {@Overridepublic 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 nameString name = generator.generateBeanName(bd, beanFactory);//注册beanbeanFactory.registerBeanDefinition(name, bd);}}}}}} catch (Exception e) {e.printStackTrace();}}
}
  • 注册该后置处理器

    context.registerBean(ComponentScanPostProcessor.class);
    

    在这里插入图片描述

模拟实现@Bean
public class AtBeanPostProcessor implements BeanFactoryPostProcessor {@Overridepublic 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扫描
public class MapperPostProcessor implements BeanDefinitionRegistryPostProcessor {@Overridepublic 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的名称,否则所有名称都是MapperFactoryBeanAbstractBeanDefinition bd2 = BeanDefinitionBuilder.genericBeanDefinition(classMetadata.getClassName()).getBeanDefinition();String name = generator.generateBeanName(bd2, beanFactory);beanFactory.registerBeanDefinition(name,bd);}}}catch (Exception e){e.printStackTrace();}}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {}
}
  • 将Mapper封装成MapperFactoryBean类型,然后注册到容器中

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/156394.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

树结构及其算法-二叉树节点的插入

目录 树结构及其算法-二叉树节点的插入 C代码 树结构及其算法-二叉树节点的插入 二叉树节点插入的情况和查找相似&#xff0c;重点是插入后仍要保持二叉查找树的特性。如果插入的节点已经在二叉树中&#xff0c;就没有插入的必要了&#xff0c;如果插入的值不在二叉树中&…

新工业革命?基于机器视觉技术分拣机器人的未来与发展

原创 | 文 BFT机器人 01 分拣机器人的应用 基于机器视觉技术的分拣机器人可以将工人从繁重的劳动中解放出来&#xff0c;大大提高了分拣的效率&#xff0c;因此被广泛地应用于食品、物流以及煤矿等多个行业。 1.1 分拣机器人在水果分拣中的应用 随着农业科技的发展和人民生活…

ES 8.x新特性一览(完整版)

一、看点 在 2022 年 2 月 11 日&#xff0c;Elasticsearch&#xff08;ES&#xff09;正式发布了 8.0 版本&#xff0c;而截止到 2023 年 10 月&#xff0c;历经一年半时间&#xff0c;ES官方已经连续发布了多个版本&#xff0c;最新版本为 8.10.4。这一系列的更新引入了众多引…

【虹科分享】Domo可视化——一份硬核的国庆出游攻略

国庆黄金周&#xff0c;正是游览祖国大好河山的好时机。然而&#xff0c;众所周知&#xff0c;“当灿烂的太阳跳出东海的碧波&#xff0c;帕米尔高原依然是群星闪烁&#xff1b;当北国还是银装素裹的世界&#xff0c;南疆早已洋溢着盎然的春色。”面对如此广阔的大地&#xff0…

NI‑9237国产化50 kS/s/ch,桥模拟输入,4通道C系列应变/桥输入模块

50 kS/s/ch&#xff0c;桥模拟输入&#xff0c;4通道C系列应变/桥输入模块 NI‑9237提供了所有的信号调理功能来实现多达四个基于桥的传感器的供电和测量。该模块提供通道间零相位延迟的应变或负载测量。它还具有60 VDC隔离和1&#xff0c;000 Vrms瞬态隔离&#xff0c;提供高…

SpringCloud 微服务全栈体系(九)

第九章 Docker 三、Dockerfile 自定义镜像 常见的镜像在 DockerHub 就能找到&#xff0c;但是我们自己写的项目就必须自己构建镜像了。 而要自定义镜像&#xff0c;就必须先了解镜像的结构才行。 1. 镜像结构 镜像是将应用程序及其需要的系统函数库、环境、配置、依赖打包而…

ArcGIS制作土地利用现状图

一、现状图成果 土地利用现状图是规划制图中一种基本的图件,基于ArcGIS制作的现状图如下所示: 二、现状图制作 1. 数据准备 (1)土地利用数据 (2)地形图 (3)影像地图 (4)其他数据 2. 符号化 加载现状地块数据。 双击地块图层,切换到符号系统,选择类别下的唯…

实现右键出现菜单选项功能

文章目录 需求分析需求 实现鼠标右键显示菜单的功能 分析 分析该需求,流程如下 写一个 div 作为右键弹出的菜单选项——> 监听鼠标右键事件——> 得到坐标位置——> 在该位置对写好的 菜单选项 进行展示——> 选择完毕后关闭菜单——> 鼠标左键其他位置 点…

C# OpenCvSharp DNN 部署L2CS-Net人脸朝向估计

效果 项目 代码 using OpenCvSharp; using OpenCvSharp.Dnn; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Linq; using System.Text; using System.Windows.Forms;namespace OpenCvSharp_DNN_Demo …

成集云 | 英克ERP对接批发销售门店 | 解决方案

方案介绍 批发连锁门店是一种以批发销售为主&#xff0c;通过连锁经营方式进行管理的商业组织形态。它通常由一个总店或总公司负责管理和运营&#xff0c;下面拥有多个分店或加盟店&#xff0c;形成一个连锁经营网络。主要业务是向下游零售商或消费者销售商品&#xff0c;因此…

图像特征Vol.1:计算机视觉特征度量|第二弹:【统计区域度量】

目录 一、前言二、统计区域度量2.1&#xff1a;图像矩特征2.1.1&#xff1a;原始矩/几何矩2.1.2&#xff1a;中心距2.1.3&#xff1a;归一化的中心矩2.1.4&#xff1a;不变矩——Hu矩2.1.5&#xff1a;OpenCv实现矩特征及其应用 2.2&#xff1a;点度量特征2.3&#xff1a;全局直…

智力测试情商测试小程序源码/带流量主提升智力微信小程序源码

智力测试情商测试小程序源码&#xff0c;这是一个考验智力&#xff0c;心理上面的一个测试游戏&#xff0c;支持多种测试方法。 比如有: 智商测试丨情商测试 | 性格测试丨爱情测试 | 抑郁症测试丨焦虑症测试 | 心理压力测试丨生活满意度测试&#xff0c;通过不同的测试&#xf…