当前位置: 首页 > news >正文

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.lryc.cn/news/214088.html

相关文章:

  • Android 14 rook替代Postern进行中间人抓包
  • [rancher] rancher部署和使用的一些思考
  • 迅镭激光董事长颜章健荣膺“2023年如皋市科技强企人物”!
  • 专业医学病例翻译公司推荐
  • 英飞凌TC3xx-Overlay
  • Win10系统有几种复制文件的命令,哪种最强大?
  • 力扣202.快乐数
  • iOS Xcode15 适配:Other Linker Flags:-ld_classic
  • springboot苍穹外卖实战:六、redis(Spring Data Redis)
  • sqli 靶场 Level23-Level30 wp
  • 《完蛋!我被美女包围了》突然火了!世界首个开源贡献榜出炉丨 RTE 开发者日报 Vol.75
  • C++ Qt 学习(一):Qt 入门
  • 高性能消息中间件 - Kafka3.x(三)
  • 【八】Linux成神之路
  • 功能测试用例,需要详细到什么程度?
  • VScode远程连接错误:进程试图写入不存在的管道
  • Python测试之Pytest详解
  • uni-app微信小程序打开第三方地图
  • Android NDK开发详解之NDK 使用入门
  • nmap指纹识别要点以及又快又准之方法
  • Rust编程基础之6大数据类型
  • 06 MIT线性代数-线性无关,基和维数Independence, basis, and dimension
  • Kubernetes 概述以及Kubernetes 集群架构与组件
  • GZ035 5G组网与运维赛题第9套
  • 使用Jasypt3.0.3版本对SpringBoot配置文件加密
  • 生成一篇博客,详细讲解springboot的单点登录功能,有流程图,有源码demo
  • Hadoop、Hive安装
  • PHP自定义函数--输入起始日期和解算日期返回日期差几天和 上一个周期的起始结束日期
  • .net 7 上传文件踩坑
  • C++基础算法④——排序算法(快速、归并附完整代码)