首页 > 其他分享 >SpringBean的实例化过程及后处理器

SpringBean的实例化过程及后处理器

时间:2024-10-28 18:16:11浏览次数:9  
标签:throws Spring void bean SpringBean 及后 处理器 public beanDefinition

SpringBean的实例化过程

我们都知道,当我们把bean交给Spring容器进行管理,也就是在xml文件中配置bean,当我们需要用到某个bean时,Spring就帮我们创建好对象使用。那我们来了解一下这中间的过程是怎样的。

1.在xml中配置bean,工厂将一整个语句配置信息转换成beanDefinition对象。注意是整条配置语句的信息,而不是某个bean。

2.beanDefinition对象然后被存储在一个叫beanDefinitionMap的Map集合中。

3.Spring框架遍历该Map集合,使用反射创建Bean实例对象,创建好后,将对象存储在单例池(singletonObjects)的Map集合中。

4.当调用getBean方法时,就从最后的Map集合中取出对象。
请添加图片描述

Spring后处理器

在原本Spring给我们一个已经比较完整的框架结构后,但是我们想让它实现某个不一样的功能时,Spring后处理器允许我们介入Bean的整个实例化过程中来进行动态注册BeanDefinition,动态修改BeanDefinition以及动态修改Bean等操作。后处理器包括以下两种,它们的区别在于作用时间段不同:

1,BeanFactoryPostProcessor:Bean工厂后处理器,它执行是在BeanDefinitionMap填充完毕,进行遍历之前。

2,BeanPostProcessor:Bean后处理器,它执行在Bean实例化后,填充到单例池之前。

1 Spring工厂后处理器

即BeanFactoryPostProcessor,它实际上是一个接口,内部提供了一个方法,只要将实现该接口的实现类交给Spring容器管理,Spring就会帮我们在它的作用时机时调用实现方法。

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("填充好BeanDefinitionMap后执行该方法");
    }
}

这个接口方法可以完成动态注册/修改BeanDefinition。

什么是动态注册Beandefinition?

可以理解为BeanDefinition对象装填到BeanDefinitionMap集合中的这一个过程。

先看动态修改BeanDefinition

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("填充好BeanDefinitionMap后执行该方法");
        //修改beanDefinition
        BeanDefinition beanDefinition = beanFactory.getBeanDefinition("Service");
        //将Service的权限名强制改为UserDao的
        beanDefinition.setBeanClassName("com.demo.impl.UserDaoImpl");
    }
}

来看控制台输出的是什么:

请添加图片描述

可以看到,原本应该输出ServiceImpl实例对象,结果却转换成了UserDaoImpl。

在刚开始输出时,报错转换错误。我们在getbean时不要进行强转,就Object就好。

再看动态注册beanDefinition

public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println("填充好BeanDefinitionMap后执行该方法");
        //注册BeanDefinition
        //创建beanDefinition
        BeanDefinition beanDefinition=new RootBeanDefinition("com.demo.impl.PersonDaoImpl");
        //转换一下才能调用下述方法->registerBeanDefinition
        DefaultListableBeanFactory defaultListableBeanFactory= (DefaultListableBeanFactory) beanFactory;
        //注册关键一步,相当于把创建的beanDefinition装在Map中
        defaultListableBeanFactory.registerBeanDefinition("personDao",beanDefinition);

    }
}

在这里,我并没有在xml中配置PersonDao的相关信息,但是也可以获得它的实例对象,这就是BeanFactoryPostProcessor帮我们做到的。

暂时先写这么多,明天继续>W<!
-------------------这是分割线------------------------
继续写完捏:

优化:

在上面,当我们想要调用注册方法时,还得强制转化一下beanFactory,不太方便,所以就有了另外一个类帮助直接调用。BeanDefinitionRegistryPostProcessor,它是BeanFactoryPostProcessor的子类。看下源码:

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

    default void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    }
}

它的使用方法如下:

public class MyBeanDefinitionRegistryPostProcessor implements org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
       // 创建beanDefinition
        BeanDefinition beanDefinition=new RootBeanDefinition("com.demo.impl.PersonDaoImpl");
        //注册关键一步,相当于把创建的beanDefinition装在Map中
        registry.registerBeanDefinition("personDao",beanDefinition);
    }

}

总的流程图:

请添加图片描述

2 Spring后处理器

BeanPostProcessor,其实基本跟beanFactoryPostProcessor实现差不多。它里面实现两个不同时机执行的方法:

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean+"postProcessBeforeInitialization方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(bean+"postProcessAfterInitialization方法");
        return bean;
    }
}

结合到bean的实例化过程中,来看下面几个方法它执行时机

首先完善一下我们的ServiceImpl。

public class ServiceImpl implements Service,InitializingBean{

    private int num;

    public void setNum(int num) {
        this.num = num;
    }

    public ServiceImpl() {
        System.out.println("bean实例化");
    }

    public void init(){
        System.out.println("自定义初始化方法执行");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean方法执行");
    }
}

然后xml配置

<bean id="Service" class="com.demo.impl.ServiceImpl" init-method="init">
        <property name="num" value="111"></property>
</bean>

然后看输出:

请添加图片描述

是不是就一目了然它们的执行先后顺序了呢。

标签:throws,Spring,void,bean,SpringBean,及后,处理器,public,beanDefinition
From: https://blog.csdn.net/Ggjvhsjsj/article/details/143245986

相关文章

  • 后端如何获得登录人的信息以及全局异常处理器
    目录后端如何获得登录人的信息全局异常处理器后端如何获得登录人的信息前提:导入jakarta.servlet-api<dependency><groupId>jakarta.servlet</groupId><artifactId>jakarta.servlet-api</artifactId><optional>true</optional><......
  • 64位处理器介绍
    64位处理器表示处理器能够处理和存储 64位(bit)宽度的数据。从技术上来说,这意味着处理器的寄存器宽度、数据总线和地址总线都可以处理64位的二进制数,从而在性能和内存寻址方面提供显著的优势。以下是详细解释:1. 基本概念64位表示处理器的寄存器可以一次性处理64位的数据。......
  • amd处理器兼容不了哪些主流软件
    AMD处理器与某些软件存在兼容问题通常归因于制造商优化、软件设计或驱动程序更新。1、专业图形和设计软件、2、某些专用游戏、3、高度优化的应用程序、4、老旧或未更新的软件。专业图形和设计软件,如某些版本的AdobePremierePro或Autodesk3dsMax,可能在针对英特尔处理器的优化......
  • [AHK2 工具] 处理器管理
    开始这是最核心的部分,用于注册、管理和调用处理器。它的前提是所有的处理器都继承于一个接口,且实现其中的方法;管理器便明确的知道如何检查处理器的合法性、及如何调用处理器。关于这个接口,在handle模块下介绍。实现以下代码实现了一个注册中心和调用中心。#Include../ha......
  • [AHK2 工具] 内置处理器
    开始内置处理器通常使用的是未开放的接口,如直接调用处理器管理器的方法;这些在用户处理器中是不会使用的,但可以由脚本提供。目前有五个内置处理器:Echo常用来查看关键字的值和测试。Exit退出程序Hist管理历史模块使用的本地文件Meow获取当前注册的处理器及调用处理器的Ec......
  • 基于全志T113-i多核异构处理器的全国产嵌入式核心板简介
    一、嵌入式核心板产品介绍基于全志公司的T113-i处理器精心设计的多核异构处理器、工业级ECK30-T13IA系列嵌入式核心板,采用邮票孔连接的低成本、低功耗、高性价比、高可靠性的全国产化工业级嵌入式核心板。ECK30系列核心板可广泛应用于工业控制、HMI、IoT等领域。全志公司的T113-......
  • 基于全志T113-i多核异构处理器的全国产嵌入式核心板简介
    一、嵌入式核心板产品介绍基于全志公司的T113-i处理器精心设计的多核异构处理器、工业级ECK30-T13IA系列嵌入式核心板,采用邮票孔连接的低成本、低功耗、高性价比、高可靠性的全国产化工业级嵌入式核心板。ECK30系列核心板可广泛应用于工业控制、HMI、IoT等领域。全志公司的T113-i处......
  • 域权限维持及后渗透密码收集
    实验目的与要求实验目的(1)理解域权限维持,能够进行域权限维持;(2)理解后渗透密码收集,能够进行后渗透密码收集。实验要求(1)能够描述黄金票据传递攻击的原理,并复现黄金票据传递攻击;(2)能够描述白银票据传递攻击的原理,并复现白银票据传递攻击;(3)能够进行后渗透密码收集。实验......
  • JavaWeb合集14-全局异常处理器
    十四、全局异常处理器全局异常处理器(GlobalExceptionHandler)是指一种机制,用于集中处理应用程序中未被捕获的异常。全局异常处理器可以用来统一处理整个应用程序中可能出现的异常,从而确保在出现未预期的错误时,程序能够以一种优雅的方式处理这些错误,并提供一致的错误响应......
  • CSS速刷 - 预处理器
    预处理器是什么?lessSass预处理器有啥功能?嵌套,反映了层级和约束变量和计算,减少了重复代码Extend和Mixin代码片段,就像具备同一个功能的函数。循环,适用于复杂有规律的样式importCSS文件模块化1.less嵌套Node写的,通过npm发布。&:同一层级2.Sass嵌套输出和less嵌套......