Java进阶-Spring-IOC

2021-11-05  本文已影响0人  GIT提交不上

一、IOC

1.1 延迟查找

  SpringFramework 4.3 中引入了一个新的 API :ObjectProvider,可以实现延迟查找

ApplicationContext context = new ClassPathXmlApplicationContext("context/beanDefine.xml");
ObjectProvider<Person> dogProvider = context.getBeanProvider(Person.class);
Person person = dogProvider.getIfAvailable(Person::new);

https://www.jianshu.com/p/27ced9a9854d

  使用场景:

1.2 @Autowired的注入原理

  先拿属性对应的类型,去 IOC 容器中找 Bean ,如果找到了一个,直接返回;如果找到多个类型一样的Bean,把属性名拿过去,跟这些 Bean 的 id 逐个对比,如果有一个相同的,直接返回;如果没有任何相同的 id 与要注入的属性名相同,则会抛出 NoUniqueBeanDefinitionException 异常。

1.3 @Autowired和@Resource区别

1.4 回调注入

  ApplicationContextAware、BeanNameAware 接口。

https://www.cnblogs.com/springmorning/p/10355859.html

1.5 FactoryBean

  ApplicationContext初始化Bean的时机默认是容器加载时就已经创建,FactoryBean本身的加载是伴随 IOC 容器的初始化时机一起的。FactoryBean生产Bean的机制是延迟生产

1.6 Bean生命周期

image.png

  在IOC容器初始化之前,默认情况下Bean已经创建好了,而且完成了初始化动作;容器调用销毁动作时,先销毁所有Bean,最后IOC容器全部销毁完成

  Bean的生命周期中,是先对属性赋值,后执行init-method标记的方法。

image.png image.png

https://juejin.cn/post/7075168883744718856

1.7 BeanFactory

image.png image.png

1.8 ApplicationContext

image.png image.png

1.9 模块装配

模块

模块装配:把一个模块需要的核心功能组件都装配好
核心原则:自定义注解 + @Import 导入组件

@Import

https://blog.csdn.net/Howinfun/article/details/118932670

1.10 条件装配

  被@Conditional注解标注的组件,只有所有指定条件都匹配时,才有资格注册。条件是可以在要注册BeanDefinition之前以编程式确定的任何状态

  实现Condition接口-条件匹配规则类

https://blog.csdn.net/weixin_46535927/article/details/119387476

1.11 组件扫描

  include的过滤规则之间互相不受影响,且不会互相排除;排除型过滤器会排除掉其他过滤规则已经包含进来的Bean

1.12 资源管理

image.png

1.13 Environment抽象

image.png image.png

1.14 BeanDefinition & BeanDefinitionRegistry

  BeanDefinition描述了一个bean的实例,该实例具有属性值,构造函数参数值以及具体实现所提供的更多信息。这只是一个最小的接口,它的主要目的是允许BeanFactoryPostProcessor(例如 PropertyPlaceholderConfigurer )内省和修改属性值和其他bean的元数据。

  BeanDefinition描述了SpringFramework中bean的元信息,它包含bean的类信息、属性、行为、依赖关系、配置信息等。BeanDefinition具有层次性,并且可以在IOC容器初始化阶段被BeanDefinitionRegistryPostProcessor构造和注册,被BeanFactoryPostProcessor拦截修改等。

image.png

  BeanDefinitionRegistry是维护BeanDefinition的注册中心,它内部存放了 IOC 容器中bean的定义信息,同时BeanDefinitionRegistry也是支撑其它组件和动态注册Bean的重要组件。在SpringFramework中,BeanDefinitionRegistry的实现是DefaultListableBeanFactory。

1.15 后置处理器

  BeanPostProcessor是一个回调机制的扩展点,它的核心工作点是在bean的初始化前后做一些额外的处理(预初始化bean的属性值、注入特定的依赖,甚至扩展生成代理对象等)。

image.png image.png

1.16 BeanFactoryPostProcessor

image.png

  BeanFactoryPostProcessor是容器的扩展点,它用于IOC容器的生命周期中,所有BeanDefinition都注册到BeanFactory后回调触发,用于访问/修改已经存在的BeanDefinition。与BeanPostProcessor相同,它们都是容器隔离的,不同容器中的BeanFactoryPostProcessor不会相互起作用。

image.png

1.17 BeanDefinitionRegistryPostProcessor

image.png

  BeanDefinitionRegistryPostProcessor是容器的扩展点,它用于 IOC 容器的生命周期中,所有BeanDefinition都准备好,即将加载到BeanFactory时回调触发,用于给BeanFactory中添加新的BeanDefinition。BeanDefinitionRegistryPostProcessor也是容器隔离的,不同容器中的BeanDefinitionRegistryPostProcessor不会相互起作用。

  BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry执行完毕后,会先执行它们的postProcessBeanFactory,然后才能轮到普通的BeanFactoryPostProcessor执行。

image.png

spring-BeanDefinitionRegistryPostProcessor、BeanFactoryPostProcessor、BeanPostProcessor三者区别

1.18 编程式驱动IOC

  refresh方法的执行,会触发非延迟加载的单实例bean的实例化和初始化。

  使用模块装配,通过标注一个@EnableJdbc的注解,能够根据当前工程中导入的数据库连接驱动,注册对应的数据源到IOC容器。

  SPI:通过一种服务寻找的机制,动态的加载接口/抽象类对应的具体实现类。它把接口具体实现类的定义和声明权交给了外部化的配置文件中。SpringFramework 中的SPI相比较于jdk原生的,不仅仅局限于接口/抽象类,它可以是任何一个类、接口、注解。

https://github.com/just-right/spring-study

1.19 事件&监听器

  子容器的事件会向上传播到父容器,父容器的事件不会向下传播

  ApplicationEventPublisher和ApplicationEventMulticaster,它们分别代表事件发布器和事件广播器。事件发布器是用来接受事件,并交给事件广播器处理;事件广播器拿到事件发布器的事件,并广播给监听器

1.20 Bean生命周期-补充

image.png

  BeanPostProcessor的扩展InstantiationAwareBeanPostProcessor可以在bean的实例化之后、初始化之前执行postProcessAfterInstantiation方法,以及postProcessProperties( postProcessPropertyValues) 方法完成属性赋值。BeanPostProcessor的回调包含bean的初始化之前和初始化之后,但DestructionAwareBeanPostProcessor只包含bean销毁回调之前的动作,没有之后。

  首先ClassPathXmlApplicationContext在refresh之前,会指定传入的xml配置文件的路径,执行refresh方法时,会初始化BeanFactory,触发xml配置文件的读取、加载和解析。其中xml的读取需要借助XmlBeanDefinitionReader ,解析xml配置文件则使用 DefaultBeanDefinitionDocumentReader ,最终解析xml中的元素,封装出BeanDefinition,最后注册到 BeanDefinitionRegistry。

  注解配置类的解析发生在BeanDefinitionRegistryPostProcessor的执行阶段,它对应的核心后置处理器是ConfigurationClassPostProcessor ,它主要负责两个步骤三件事情:解析配置类、注册BeanDefinition。三件事情包括:1) 解析@ComponentScan 并进行包扫描,实际进行包扫描的组件是ClassPathBeanDefinitionScanner ;2) 解析配置类中的注解(如 @Import 、@ImportResource 、@PropertySource 等)并处理,工作的核心组件是ConfigurationClassParser ;3) 解析配置类中的 @Bean并封装BeanDefinition,实际解析的组件是ConfigurationClassBeanDefinitionReader。

image.png image.png image.png

1.21 参考链接

https://www.jianshu.com/p/1dec08d290c1
https://juejin.cn/book/6857911863016390663/section/6867492434910117902
https://juejin.cn/post/6956814839729618957

上一篇下一篇

猜你喜欢

热点阅读