美文网首页
Java进阶-Spring-IOC

Java进阶-Spring-IOC

作者: GIT提交不上 | 来源:发表于2021-11-05 19:41 被阅读0次

    一、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

      使用场景:

    • 可以让依赖的资源充分等到初始化完成之后再使用
    • 可以和@Lazy注解配合充分实现延迟初始化
    • 可用于解决构造器级别的循环依赖

    1.2 @Autowired的注入原理

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

    1.3 @Autowired和@Resource区别

    • 构造器注入/setter注入

    • @Autowired 按类型注入, 可指定required=false来避免注入失败

    • @Resource 按名称注入,相当于@Autowired+@Qualifier

    1.4 回调注入

      ApplicationContextAware、BeanNameAware 接口。

    • 当ApplicationContext创建了一个实现ApplicationContextAware接口的对象实例时,就为该实例提供了ApplicationContext引用
    • 当ApplicationContext创建实现BeanNameAware接口的类时,该类提供了在其关联对象定义中定义的名称的引用

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

    1.5 FactoryBean

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

    • BeanFactory :SpringFramework 中实现IOC的最底层容器(此处的回答可以从两种角度出发:从类的继承结构上看,它是最顶级的接口,也就是最顶层的容器实现;从类的组合结构上看,它则是最深层次的容器,ApplicationContext在最底层组合了BeanFactory)
    • FactoryBean :创建对象的工厂Bean,可以使用它来直接创建一些初始化流程比较复杂的对象。
    • FactoryBean的生命周期与IOC容器一致,而FactoryBean生产bean的时机是延迟创建的。

    1.6 Bean生命周期

    image.png

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

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

    • init-method & destroy-method
    • @PostConstruct & @PreDestroy
    • InitializingBean & DisposableBean
    image.png image.png

    https://juejin.cn/post/7075168883744718856

    1.7 BeanFactory

    image.png
    • HierarchicalBeanFactory
    • ListableBeanFactory
    image.png
    • AutowireCapableBeanFactory
    • ConfigurableBeanFactory
    • AbstractBeanFactory(getBeanDefinition/createBean)
    • AbstractAutowireCapableBeanFactory
    • DefaultListableBeanFactory

    1.8 ApplicationContext

    image.png
    • AbstractApplicationContext - refresh
    image.png

    1.9 模块装配

    模块

    • 独立的
    • 功能高内聚
    • 可相互依赖
    • 目标明确

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

    @Import

    • 导入普通类
    • 导入ImportSelector接口实现类
    • 导入ImportBeanDefinitionRegistrar实现类

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

    1.10 条件装配

    • @Profile
        默认default
        基于环境的配置:根据当前项目的运行时环境不同,可以动态的注册当前运行环境匹配的组件。

    • @Conditional

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

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

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

    1.11 组件扫描

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

    1.12 资源管理

    image.png
    • ProtocolResolver
    • DefaultResourceLoader
    • @PropertySource
    • PropertySourceFactory
    • DefaultPropertySourceFactory

    1.13 Environment抽象

    image.png
    • Environment中包含profiles和properties,这些配置信息会影响IOC容器中的bean的注册与创建;
    • Environment的创建是在ApplicationContext创建后才创建的,所以Environment应该是伴随着ApplicationContext的存在而存在
    • ApplicationContext中同时包含Environment和组件bean ,而且从BeanFactory的视角来看,Environment 也是一个Bean,只不过它的地位比较特殊。
    image.png

    1.14 BeanDefinition & BeanDefinitionRegistry

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

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

    image.png
    • BeanDefinition继承了AttributeAccessor 接口,具有配置bean属性的功能;

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

    • BeanFactoryPostProcessor,可实现去除beanDefinition
    • BeanDefinition的合并

    1.15 后置处理器

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

    • BeanPostProcessor的执行可以指定先后顺序,实现Ordered接口;
    • BeanPostProcessor作用于bean对象的创建后,不同IOC容器中的BeanPostProcessor不会互相起作用
    • BeanPostProcessor提供了两个回调时机:bean的初始化之前和bean的初始化之后,它们分别适合做填充和代理的工作;
    image.png
    • postProcessBeforeInitialization是用来填充的,而工厂就是做的这事。如果使用FactoryBean就是说用户已经把想填充的内容在工厂里做好了,spring不应该再插手,所以不会调用postProcessBeforeInitialization。
    image.png
    • InstantiationAwareBeanPostProcessor
    • SmartInstantiationAwareBeanPostProcessor
    • DestructionAwareBeanPostProcessor
    • MergedBeanDefinitionPostProcessor

    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 事件&监听器

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

    • ApplicationEvent/ApplicationListener/PayloadApplicationEvent/

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

    1.20 Bean生命周期-补充

    • BeanDefinition部分
      • BeanDefinition的解析
      • BeanDefinition的注册
    • bean实例部分
      • bean的实例化
      • bean的属性赋值+依赖注入
      • bean的初始化流程
      • bean的启动与停止
      • 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

    相关文章

      网友评论

          本文标题:Java进阶-Spring-IOC

          本文链接:https://www.haomeiwen.com/subject/wcfhzltx.html