BeanPostProcessor后置处理器原理以及ApplicationListener原理

  BeanPostProcessor:bean后置处理器,bean创建对象初始化前后进行拦截工作的

  1、BeanFactoryPostProcessor:BeanFactory的后置处理器;

  在BeanFactory标准初始化之后调用;所有的bean定义已经保存加载到BeanFactory,但是bean的实例还没创建;

  BeanFactoryPostProcessor原理:

  1.1 ioc容器创建对象

  1.2 invokeBeanFactoryPostProcessors(BeanFactory); 执行BeanFactoryPostProcessor;

  如何找到所有的BeanFactoryPostProcessor并执行他们的方法;

  1.2.1 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法

  1.2.2 在初始化创建其他组件前面执行

  2、BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor

  postProcessBeanDefinitionRegistry();

  在所有bean定义信息将要被加载,bean实例还未创建的;

  优先于BeanFactoryPostProcessor执行;

  利用BeanDefinitionRegistryPostProcessor给容器中在额外添加一些组件;

  原理:

  2.1、ioc创建对象

  2.2、refresh()->invokeBeanFactoryPostProcessors(beanFactory);

  2.3、从容器中获取到的BeanDefinitionRegistryPostProcessor组件。

  2.3.1 依次触发所有的postProcessBeanDefinitionRegistry()方法

  2.3.2 再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;

  2.4、再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法

  3、ApplicationListener:监听容器中发布的事件。事件驱动模型开发;

  public interface ApplicationListener

  监听ApplicationEvent 及其下面的子事件;

  步骤:

  1、写一个监听器来监听某个事件(ApplicationEvent及其子类)

  2、把监听器加入到容器;

  3、只要容器中有相关事件的发布,我们就能监听到这个事件;

  ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;

  ContextClosedEvent:关闭容器会发布这个事件;

  4、发布一个事件;

  applicationContext.publishEvent();

  原理:

  ContextRefreshedEvent、IOCTest_Ext$1[source=自己的事件!!]、ContextClosedEvent;

  1、ContextRefreshedEvent事件:

  1.1 容器创建对象:refresh();

  1.2 finishRefresh();容器刷新完成会发布ContextRefreshedEvent

  1.3 publishEvent(new ContextRefreshedEvent(this));【事件发布流程】

  1.3.1 获取事件的多波器(派发器):getApplicationEventMulticaster()

  1.3.2 MulticasterEvent派发事件:

  1.3.3 获取到所有的ApplicationListener

  for(final ApplicationListener listener : getApplicationListeners(event, type))

  1.3.3.1 如果有Executor,可以支持使用Executor进行异步派发;

  Executor executor = getTaskExecutor();

  1.3.3.2 否则,同步的方式直接执行listener方法;invokeListener(listener, event);

  拿到listener回调onApplicationEvent方法;

  2、发布自己的事件;

  3、容器关闭会发布ContextClosedEvent

  【事件多波器(派发器)】

  1、容器创建对象:refresh();

  2、initApplicationEventMulticaster();初始化ApplicationEventMulticaster;

  2.1 先去容器中找到有没有id="applicationEventMultcaster"的组件;

  2.2 如果没有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);

  并且加入到容器中,我们就可以在其他组件要派发事件,自动注入这个applicationEventMulticaster;

  【容器中有哪些监听器】

  1、容器创建对象:refresh();

  2、registerListeners();

  String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);

  //将listener注册到ApplicationEventMulticaster中

  getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

  package com.spring.ext;

  import org.springframework.context.annotation.Bean;

  import org.springframework.context.annotation.ComponentScan;

  import org.springframework.context.annotation.Configuration;

  import com.spring.bean.Red;

  @ComponentScan("com.spring.ext")

  @Configuration

  public class ExtConfig {

  @Bean

  public Red blue() {

  return new Red();

  }

  }

  package com.spring.ext;

  import org.springframework.context.ApplicationEvent;

  import org.springframework.context.ApplicationListener;

  import org.springframework.stereotype.Component;

  @Component

  public class MyApplicationListener implements ApplicationListener{

  public void onApplicationEvent(ApplicationEvent event) {

  System.out.println("event>>>>>>>>"+event);

  }

  }

  package com.spring.ext;

  import java.util.Arrays;

  import org.springframework.beans.BeansException;

  import org.springframework.beans.factory.config.BeanFactoryPostProcessor;

  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

  import org.springframework.stereotype.Component;

  @Component

  public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

  System.out.println("MyBeanFactoryPostProcessor ... postProcessBeanFactory beansize="+beanFactory.getBeanDefinitionCount());

  int count = beanFactory.getBeanDefinitionCount();

  String[] names = beanFactory.getBeanDefinitionNames();

  System.out.println("当前BeanFactory中有"+count+"个Bean");

  System.out.println(Arrays.toString(names));

  }无锡人流医院哪家好 http://mobile.wxbhnkyy120.com/

  }

  package com.spring.ext;

  import org.springframework.beans.BeansException;

  import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

  import org.springframework.beans.factory.support.AbstractBeanDefinition;

  import org.springframework.beans.factory.support.BeanDefinitionBuilder;

  import org.springframework.beans.factory.support.BeanDefinitionRegistry;

  import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

  import org.springframework.stereotype.Component;

  import com.spring.bean.Red;

  @Component

  public class MyBenaDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

  System.out.println("MyBenaDefinitionRegistryPostProcessor ..beansize ="+beanFactory.getBeanDefinitionCount());

  }

  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

  System.out.println(">>>>>postProcessBeanDefinitionRegistry>>>beansize="+registry.getBeanDefinitionCount());

  AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Red.class).getBeanDefinition();

  registry.registerBeanDefinition("hello", beanDefinition);

  }

  }

  package com.spring.ext;

  import org.springframework.context.ApplicationEvent;

  import org.springframework.context.event.EventListener;

  import org.springframework.stereotype.Service;

  @Service

  public class UserService {

  @EventListener(classes= {ApplicationEvent.class})

  public void listener(ApplicationEvent event) {

  System.out.println("自己监听><>>>>>>"+event);

  }

  }

  package com.spring.test;

  import org.junit.Test;

  import org.springframework.context.ApplicationEvent;

  import org.springframework.context.annotation.AnnotationConfigApplicationContext;

  import com.spring.ext.ExtConfig;

  public class IOCTestOfExt {

  @Test

  public void test01() {

  AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);

  applicationContext.publishEvent(new ApplicationEvent("自己的事件!!") {

  });

  applicationContext.close();

  }

  }

原文地址:https://www.cnblogs.com/djw12333/p/11200554.html

时间: 2024-10-02 18:39:31

BeanPostProcessor后置处理器原理以及ApplicationListener原理的相关文章

Spring之BeanPostProcessor(后置处理器)介绍

??为了弄清楚Spring框架,我们需要分别弄清楚相关核心接口的作用,本文来介绍下BeanPostProcessor接口 BeanPostProcessor ??该接口我们也叫后置处理器,作用是在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑.注意是Bean实例化完毕后及依赖注入完成后触发的.接口的源码如下 public interface BeanPostProcessor { /** * Apply this BeanPostProcessor to th

Spring中的后置处理器BeanPostProcessor讲解

BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中. package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.B

Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解

BeanPostProcessor接口作用: 如果我们想在Spring容器中完成bean实例化.配置以及其他初始化方法前后要添加一些自己逻辑处理.我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中. package com.test.spring; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.B

spring 后置处理器BeanFactoryPostProcessor和BeanPostProcessor的用法和区别

主要区别就是: BeanFactoryPostProcessor可以修改BEAN的配置信息而BeanPostProcessor不能,下面举个例子说明 BEAN类: [java] view plaincopy package com.springdemo.postProcessor; public class PostProcessorBean { private String username; private String password; public String getPassword

Bean后置处理器 BeanPostProcessor

1.BeanPostProcessor接口的作用 Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理,Bean后置处理器对IOC容器的所有bean实例逐一处理,而非单一实例. 我们可以定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IOC容器中. 2.BeanPostProcess接口的api public interface BeanPostProcessor { /** * Apply this BeanPostProcessor to t

BeanPostProcessor bean 的后置处理器

一.MyBeanPostProcessor 类,自定 bean 的后只处理器类.当你在初始化容器中的 bean 之前和之后,都会调用该处理器中的方法 @Component //将该后后置处理器加入到容器中 public class MyBeanPostProcessor implements BeanPostProcessor { /** * 任何初始化方法调用之前,都会先执行本方法 * Object bean:容器刚刚创建的实例 * String beanName:该实例在容器中的名字 */

[原创]java WEB学习笔记101:Spring学习---Spring Bean配置:IOC容器中bean的声明周期,Bean 后置处理器

本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 -----------------------------------------------------------------------------------------------------------------

Spring的Bean的生命周期以及Bean的后置处理器

Bean的生命周期: Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务. Spring IOC 容器对 Bean 的生命周期进行管理的过程: 1通过构造器或工厂方法创建 Bean 实例 2为 Bean 的属性设置值和对其他 Bean 的引用 3调用 Bean 的初始化方法(可以人为指定,利用Bean标签的inti-method属性指定初始化方法,不指定就默认忽略这步骤) Bean 可以使用了 4当容器关闭时, 调用 Bea

曹工杂谈:为什么很少需要改Spring源码,因为扩展点太多了,说说Spring的后置处理器

前言 最近发了好几篇,都是覆盖框架源码,但是spring的代码,我是从没覆盖过,毕竟,如果方便扩展,没谁想去改源码,而spring就是不需要改源码的那个,真的是"对扩展开放,对修改关闭"的典范. 就我说曾经用过的,spring的扩展点,就包括了listener.beanFactoryPostProcessor.beanPostProcessor,而spring boot的扩展点,除了properties.yml.java config覆盖自动配置.org.springframework