(四)、扩展原理
1.BeanFactoryPostProcessor ->来定制和修改beanFactory的内容
在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建
1.判断无参构造函数创建实列是否在BeanFactory之前还是之后?
1.BeanFactory的后置处理器MyBeanFactoryPostProcessor
package com.jsxs.etx; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.stereotype.Component; import java.util.Arrays; /** * @Author Jsxs * @Date 2023/8/24 10:44 * @PackageName:com.jsxs.etx * @ClassName: MyBeanFactoryPostProcessor * @Description: TODO * @Version 1.0 */ @Component ⭐注册组件 public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { ⭐⭐ 继承接口 @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("MyBeanFactoryPostProcessor->执行力postProcessBeanFactory方法"); // 组件的数量 int count = beanFactory.getBeanDefinitionCount(); // 组件的名字 String[] names = beanFactory.getBeanDefinitionNames(); System.out.println("当前beanFactory中有"+count+"个Bean"); System.out.println(Arrays.asList(names)); } }
2.实体类
package com.jsxs.bean; /** * @Author Jsxs * @Date 2023/8/13 21:11 * @PackageName:com.jsxs.bean * @ClassName: Yellow * @Description: TODO * @Version 1.0 */ public class Yellow { public Yellow() { // ⭐构造函数 System.out.println("Yellow无参构造创建实列"); } }
3.配置类
package com.jsxs.etx; import com.jsxs.bean.Yellow; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * @Author Jsxs * @Date 2023/8/24 10:38 * @PackageName:com.jsxs.etx * @ClassName: EtxConfig * @Description: TODO BeanFactoryPostProcessor : beanFactory的后置处理器 ⭐ * 在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建 * 在初始化创建其他组件前面执行 * @Version 1.0 */ @ComponentScan("com.jsxs.etx") ⭐扫面组件 @Configuration public class EtxConfig { @Bean ⭐⭐ 将组件注册进来 public Yellow yellow(){ return new Yellow(); } }
4.测试
package com.jsxs.Test; import com.jsxs.etx.EtxConfig; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** * @Author Jsxs * @Date 2023/8/24 10:48 * @PackageName:com.jsxs.Test * @ClassName: IOC_ext * @Description: TODO * @Version 1.0 */ public class IOC_ext { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EtxConfig.class); applicationContext.close(); } }
所有的bean已经保存到beanFactory工厂中,但是实列依然还没有创建。在初始化创建其他组件前面执行
2.BeanDefinitionRegistryPostProcessor -> 额外添加组件
1.注册后置处理器
package com.jsxs.etx; import com.jsxs.bean.Yellow; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.stereotype.Component; /** * @Author Jsxs * @Date 2023/8/24 11:09 * @PackageName:com.jsxs.etx * @ClassName: MyBeanDefinitionRegistryPostProcessor * @Description: TODO * @Version 1.0 */ @Component ⭐ public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { // BeanDefinitionRegistry Bean定义信息的保存中心,以后BeanFactory就是按照BeanDefinitionRegistry里面保存的每一个bean定义信息创建bean实列 ⭐⭐ @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("MyBeanDefinitionRegistryPostProcessor的数量是 "+registry.getBeanDefinitionCount()+"Registry "); // 创建一个组件 ⭐⭐⭐ RootBeanDefinition beanDefinition = new RootBeanDefinition(Yellow.class); // 将刚才创建的组件注册进IOC中,且名字叫做hello ⭐⭐⭐⭐ registry.registerBeanDefinition("hello",beanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("MyBeanDefinitionRegistryPostProcessor的数量是:"+beanFactory.getBeanDefinitionCount()+" BeanFactory"); } }
2. 配置类 EtxConfig.java MyBeanFactoryPostProcessor.java Yellow.java IOC_ext.java 和上面的类是一样的
package com.jsxs.etx; import com.jsxs.bean.Yellow; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * @Author Jsxs * @Date 2023/8/24 10:38 * @PackageName:com.jsxs.etx * @ClassName: EtxConfig * @Description: TODO 1. BeanFactoryPostProcessor : beanFactory的后置处理器 * 在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建 * 在初始化创建其他组件之前运行 * (1).原理 * (1.1).创建IOC容器 * * 2.BeanDefinitionRegistryPostProcessor * 在所有的bean定义信息将要被加载,bean实列还未创建的时候执行。 * 优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外的添加一些组件 * (2).原理 * (2.1).创建IOC容器 * (2.2).refresh() 刷新容器 ->invokeBeanFactoryPostProcessors(beanFactory);. * * * * @Version 1.0 */ @ComponentScan("com.jsxs.etx") @Configuration public class EtxConfig { @Bean public Yellow yellow(){ return new Yellow(); } }
3.ApplicationListener -> 应用监听器
(1).ApplicationListener 的应用
1.事件-接口
package com.jsxs.etx; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; /** * @Author Jsxs * @Date 2023/8/24 11:59 * @PackageName:com.jsxs.etx * @ClassName: MyApplicationListener * @Description: TODO * @Version 1.0 */ @Component ⭐ public class MyApplicationListener implements ApplicationListener<ApplicationEvent> { // 当容器中发布此事以后,方法触发 ⭐⭐ @Override public void onApplicationEvent(ApplicationEvent event) { System.out.println("收到事件"+event); } }
2.自定义事件
package com.jsxs.Test; import com.jsxs.etx.EtxConfig; import org.springframework.context.ApplicationEvent; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** * @Author Jsxs * @Date 2023/8/24 10:48 * @PackageName:com.jsxs.Test * @ClassName: IOC_ext * @Description: TODO * @Version 1.0 */ public class IOC_ext { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(EtxConfig.class); // 1.自定义发布一个事件 ⭐⭐⭐ applicationContext.publishEvent(new ApplicationEvent(new String("我发布了一个事件")) { }); applicationContext.close(); } }
3.配置类等其他的都没有变化
package com.jsxs.etx; import com.jsxs.bean.Yellow; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; /** * @Author Jsxs * @Date 2023/8/24 10:38 * @PackageName:com.jsxs.etx * @ClassName: EtxConfig * @Description: TODO 1. BeanFactoryPostProcessor : beanFactory的后置处理器 * 在BeanFactory标准初始化之后调用,所有的bean定义已经保存加载到beanFactory,但是bean的实列还未创建 * 在初始化创建其他组件之前运行 * (1).原理 * (1.1).创建IOC容器 * * 2.BeanDefinitionRegistryPostProcessor * 在所有的bean定义信息将要被加载,bean实列还未创建的时候执行。 * 优先于BeanFactoryPostProcessor执行,利用BeanDefinitionRegistryPostProcessor给容器中再额外的添加一些组件 * (2).原理 * (2.1).创建IOC容器 * (2.2).refresh() 刷新容器 ->invokeBeanFactoryPostProcessors(beanFactory);. * 3.ApplicationListener 监听容器中发布的事件。事件驱动模型开发 * (1).监听ApplicationEvent及其下面的子事件 * * 步骤: * (1).写一个监听器来监听某个事件(ApplicationEvent及其子类) * (2).把监听器加入到容器中 * (3).只要容器中有相关事件的发布,我们就能监听到这个事件 * ContextRefreshedEvent ->刷新事件 (所有的bean都已经创建) * ContextClosedEvent -> 关闭事件 * (4).自定义事件 ⭐⭐⭐⭐ * applicationContext.publishEvent(new ApplicationEvent(new String("我发布了一个事件")) {}); * * * * * @Version 1.0 */ @ComponentScan("com.jsxs.etx") @Configuration public class EtxConfig { @Bean public Yellow yellow(){ return new Yellow(); } }