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

Spring底层原理(二)

Spring底层原理(二)

BeanFactory的实现
//创建BeanFactory对象
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//注册Bean定义对象
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(SpringConfig.class).setScope("singleton").getBeanDefinition();
factory.registerBeanDefinition("config",beanDefinition);
for (String name : factory.getBeanDefinitionNames()) {System.out.println(name);
}

使用AnnotationConfigUtils为容器添加后置处理器

//给BeanFactory添加一些常用的后置处理器,对BeanFactory功能进行增强
AnnotationConfigUtils.registerAnnotationConfigProcessors(factory);
Spring自带的后置处理器
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
  • internalConfigurationAnnotationProcessor:对@Configuration@Bean注解进行解析处理,为BeanFactory后置处理器

  • internalAutowiredAnnotationProcessor:对@Autowired注解进行解析处理,是Bean后置处理器

  • internalCommonAnnotationProcessor:对@Resource注解进行解析处理,是Bean后置处理器

执行BeanFactory后置处理器

Map<String, BeanFactoryPostProcessor> factoryPostProcessorMap = factory.getBeansOfType(BeanFactoryPostProcessor.class);
for (BeanFactoryPostProcessor processor : factoryPostProcessorMap.values()) {processor.postProcessBeanFactory(factory);
}
  • 需要调用这些后置处理器的postProcessBeanFactory方法,这些处理器才会生效

BeanFactory后置处理器主要功能:补充了一些bean的定义

关联BeanBean后置处理器

factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);

Bean后置处理器:针对Bean的生命周期的各个阶段提供拓展,例如@Autowired @Resource

💡BeanFactry中的单例对象并不是预先就创建好的,而是第一次从容器中获取时才进行创建

在这里插入图片描述

如何将这些单例bean预实例化呢?

factory.preInstantiateSingletons();
  • 该方法将所有单例对象进行预实例化

在这里插入图片描述

总结

beanFactory不会做的事

  • 不会主动调用BeanFactory后置处理器
  • 不会主动添加Bean后置处理器
  • 不会主动初始化单例
  • 不会解析beanFactory,也不会解析${}#{}

bean后置处理器会有排序的逻辑

  • AnnotationConfigUtils在调用registerAnnotationConfigProcessors方法后,会自动设置一个排序比较器供后续使用

    在这里插入图片描述

    //默认采用list的排序规则   
    public static void sort(List<?> list) {if (list.size() > 1) {list.sort(INSTANCE);}
    }
    
  • 排序时会调用后置处理器的getOrder方法,该方法会返回一个整数,根据整数排序

    • CommonAnnotationBeanPostProcessor

      this.setOrder(2147483644);
      
    • AutowiredAnnotationBeanPostProcessor

      private int order = 2147483645;
      

    所以当AutowiredResource注解同时使用时会根据后置处理器的顺序决定谁生效

  • 测试排序规则

    ArrayList<Integer> integers = new ArrayList<>();
    integers.add(2147483644);
    integers.add(2147483645);
    integers.sort(AnnotationAwareOrderComparator.INSTANCE);
    //[2147483644, 2147483645]
    
    • 数字越小优先级越高,所以@Resource的优先级更高
ApplicationContext
ClassPathApplicationContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="bean1" class="com.vmware.entity.Bean1"/><bean id="bean2" class="com.vmware.entity.Bean2"><property name="bean1" ref="bean1"/></bean>
</beans>
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {System.out.println(name);
}
  • 较为经典的容器,基于classpath下的xml格式的配置文件来创建
FileSystemXmlApplicationContext
FileSystemXmlApplicationContext applicationContext=new FileSystemXmlApplicationContext("D:\\spring-simple\\src\\main\\resources\\applicationContext.xml");
String[] names = applicationContext.getBeanDefinitionNames();
for (String name : names) {System.out.println(name);
}
  • 基于磁盘路径下xml格式的配置文件来创建

📖它们是如何将xml配置文件解析完成并加入到beanFactory呢?

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader= new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
  • ClassPathApplicationContext内部会自动创建一个DefaultListableBeanFactory,然后通过XmlBeanDefinitionReaderClassPathResource对配置文件进行加载并解析,然后将bean加载到容器中

  • FileSystemXmlApplicationContextClassPathApplicationContext类似,只是通过FileSystemResource对配置文件进行加载

  • 默认情况下使用这两个容器并不会自动引入spring自带的后置处理器,可以使用标签<context:annotation-config/>进行引入

AnnotationConfigApplicationContext
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(Config.class);
  • 基于java配置类来创建容器
  • 会自动注册spring自带的后置处理器到容器中,同时配置类也会被注册到容器中
AnnotationConfigServletWebServerApplicationContext
AnnotationConfigServletWebServerApplicationContext applicationContext = new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);@Configuration
static class WebConfig{//注册内嵌Web服务器工厂@Beanpublic ServletWebServerFactory servletWebServerFactory(){return new TomcatServletWebServerFactory();}//注册请求分发器@Beanpublic DispatcherServlet dispatcherServlet(){return new DispatcherServlet();}//关联WebServer与DispatcherServlet@Beanpublic DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet){return new DispatcherServletRegistrationBean(dispatcherServlet,"/");}//注册controller,bean的名称如果以/开头,则该名称即为请求路径@Bean("/hello")public Controller controller1(){return (httpServletRequest, httpServletResponse) -> {httpServletResponse.getWriter().write("hello");return null;};}}

在这里插入图片描述

  • 这是一个经典的容器,基于java配置类来创建,用于web环境
http://www.lryc.cn/news/204351.html

相关文章:

  • springboot188基于spring boot的校园商铺管理系统
  • 【计网 DNS】计算机网络 DNS协议详解:中科大郑烇老师笔记 (六)
  • vue 生命周期钩子函数 mounted()实例
  • 数据分享 I 地级市人口和土地使用面积基本情况
  • 被邀请为期刊审稿时,如何做一个合格的审稿人?官方版本教程来喽
  • 数据飞轮拆解车企数据驱动三板斧:数据分析、市场画像、A/B 实验
  • 基于PyQt5和OpenCV库的简单的文档对齐扫描应用程序
  • 【3D 图像分割】基于 Pytorch 的 VNet 3D 图像分割2(基础数据流篇)
  • HDR图像处理软件 Photomatix Pro mac中文版新增功能
  • 【Kotlin精简】第5章 简析DSL
  • 2021年06月 Python(一级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • MySQL执行计划分析
  • 【数据结构与算法】Snowflake雪花算法Java实现
  • 重要功能更新:妙手正式接入SHEIN供货模式(OBM)店铺,赋能卖家把握出海新机遇!
  • 和鲸ModelWhale与中科可控X系列异构加速服务器完成适配认证,搭载海光芯片,构筑AI算力底座
  • Vue单文件组件
  • 轻松理解 Transformers(1):Input部分
  • PHP MySQL 交互 笔记/练习
  • 领域驱动设计:基于DDD的微服务设计实例
  • 【PB续命02】Oracle中加密及编码等
  • STM32-LTC6804方案成熟BMS方案
  • 一步一步认知机器学习
  • 现代C++、STL、QTL的使用
  • Android 备案公钥、签名 MD5获取方法
  • 1688拍立淘接口,按图搜索商品接口,图片识别接口,图片上传搜索接口,图片搜索API接口,以图搜货接口
  • H3C AC通过Web平台进行AC软件的升级?
  • 网络通信和tcp协议
  • React 核心与实战2023版
  • 在 Android 上测试 Kotlin 协程
  • 图论04-【无权无向】-图的广度优先遍历BFS