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

Spring实例化的基本流程和Bean处理器

目录

Spring实例化的基本流程

Bean的处理器

Bean工厂后处理器(BeanFactoryPostProcessor)

动态注册beanDefinition

Bean后处理器(BeanPostProcessor)


Spring实例化的基本流程

    在了解处理器之前,要清除spring实例化对象的基本流程:

  1. 解析spring.xml文件,封装成BeanDefinition
  2. 将这些BeanDefinition存放到BeanDefinitionMap内
  3. 遍历Map,得到Bean
  4. 将Bean存放到singletonObjects
  5. 通过调用getBean方法得到bean

图解:

 

Bean的处理器

概念:Spring的后处理器是Spring对外开发的重要扩展点,它允许我们介入到Bean的整个实例化流程中来, 可以动态添加、修改BeanDefinition,动态修改Bean。

Spring主要有两种处理器:一种是Bean工厂后处理器,另一种是Bean后处理器

区别:

Bean工厂后处理器在BeanDefinitionMap填充完毕,Bean实例化之前执行;

Bean后处理器一般在bean实例化后,填充到单例池SingletonObjectes之前执行。

 

Bean工厂后处理器(BeanFactoryPostProcessor)

BeanFactoryPostProcessor是一个接口规范,实现该接口的类只需交给Spring容器管理,spring就会调用该接口的方法;

该方法在Bean实例化之前执行,因此可以实现,使用gwtBean获取id为“a”的bean,但返回的结果是B类的bean:


public class MyBfpp implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {

        BeanDefinition a = bf.getBeanDefinition("a");
        a.setBeanClassName("com.cc.ClassB");

    }
}

 使用getBean获取“a”

public class Main {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("bfpp.xml");
        Object bean = app.getBean("a");
        System.out.println(bean);
    }
}

 返回的结果为B类的对象,实现“偷梁换柱”的效果

 

动态注册beanDefinition

如果有一个类没有交给spring容器处理,但是在工厂后处理器这里手动添加进去,这样也可以使用getBean获取

步骤:

  1. 创建一个beanDefinition对象(new RootBeanDefiniton)
  2. 用该对象设置类的全限定名
  3. 动态注册到BeanDefinitionMap中  (DefaultListableBeanFactory) 

 示例:将为被配置的ClassC动态注册到spring中:

public class MyBfpp implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        beanDefinition.setBeanClassName("com.cc.ClassC");
        //注册的方法在DefaultListableBeanFactory里面,所以需要把beanFactory强转一下
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) bf;
        defaultListableBeanFactory.registerBeanDefinition("ccc",beanDefinition);
    }
}

直接使用getBean("ccc")看是否能获取到对象:

 

 

Bean后处理器(BeanPostProcessor)

 Bean后处理器也是一个接口,但是它的执行时间是对象创建之后,实现该接口需要重写两个方法,分别在bean的初始化前和初始化后执行:

public class MyBpp implements BeanPostProcessor {
    //初始化之前
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("AfterInitialization....");
        return bean;
    }

    //初始化之后
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeforeInitialization");
        return bean;
    }
}

注意:想要看到打印结果,需要将一些类交给spring管理才会执行这些方法! 

示例:

写了一个A类和B类交给spring容器管理,并且使用init-method调用初始化方法:

    <bean class="com.cc.ClassA" id="a" init-method="aInit"></bean>
    <bean class="com.cc.ClassB" id="b" init-method="bInit"></bean>

可以看到执行顺序为 postProcessBeforeInitialization -> 初始化方法 -> postProcessAfterInitialization

 

那么现在可以完善一下spring实例化对象的基本流程图:


http://www.kler.cn/a/447000.html

相关文章:

  • 让汉语和英语一样长的字符编码
  • 两点间最短距离 - Dijkstra
  • 音视频入门基础:MPEG2-TS专题(21)——FFmpeg源码中,获取TS流的视频信息的实现
  • 详解 Qt WebEngine 模块
  • 深入理解ER模型:数据库设计的核心工具与应用
  • Python国内10个镜像源-地址汇总以及测评
  • LeetCode 2545.根据第 K 场考试的分数排序:考察编程语言的排序
  • 现代 CSS 布局与响应式设计实战指南
  • asp.net多媒体教室管理系统VS开发sqlserver数据库web结构c#编程计算机网页项目
  • 使用Mac自带共享实现远程操作
  • TANGO与LabVIEW控制系统集成
  • [ESP]从零开始的Arduino IDE安装与ESP环境配置教程
  • HBase、Hive、Redis 和 MongoDB的对比
  • C语言的函数指针
  • linux-----文件命令
  • Latex 转换为 Word(使用GrindEQ )(英文转中文,毕业论文)
  • AdminJS - 集成 MySQL 的现代化管理面板开发指南
  • CSS3 实现火焰-小火苗效果
  • linux中大内核锁、互斥锁、信号量、完成变量、自旋锁区别
  • 【AIGC-ChatGPT进阶提示词-《动图生成》】怪物工厂:融合想象力与创造力的奇幻世界
  • vscode 使用说明
  • 四川托普信息技术职业学院教案1
  • 智能挂号系统设计典范:SSM 结合 Vue 在医院的应用实现
  • Windows下安装Rabbit MQ
  • 【线性代数】理解矩阵乘法的意义(点乘)
  • 安装Mac软件遇到问题常见报错