05.Spring Framework 之擴展機制

1. BeanFactory 後置處理器

1.1 概述

BeanFactory 後置處理器有兩種類型,分別是 BeanFactoryPostProcessor 和 BeanDefinitionRegistryPostProcessor

BeanFactoryPostProcessor 在 BeanFactory 標準初始化之後調用,用來定製和修改 BeanFactory 的內容,所有的 bean 定義已經保存加載到 beanFactory,但是 bean 的實例還未創建

BeanDefinitionRegistryPostProcessor 在所有 bean 定義信息將要被加載時觸發,優先於 BeanFactoryPostProcessor 執行,利用 BeanDefinitionRegistryPostProcessor 可以給容器再額外添加一些組件

BeanDefinitionRegistry:Bean 定義信息的保存中心,以後 BeanFactory 就是按照 BeanDefinitionRegistry 裏面保存的每一個 bean 定義信息創建 bean 實例

1.2 執行順序

BeanFactory 後置處理器執行流程

1.3 環境搭建

代碼已經上傳至 https://github.com/masteryourself-tutorial/tutorial-spring ,詳見 tutorial-spring-framework/tutorial-spring-framework-beanfactorypostprocessor 工程

1. MyBeanDefinitionRegistryPostProcessor
@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println(String.format(">>>>>>>>>>>>>>>> {%s} %s", "MyBeanDefinitionRegistryPostProcessor", "postProcessBeanFactory 執行了"));
        System.out.println(String.format(">>>>>>>>>>>>>>>> {%s} bean 的數量 %d", "MyBeanDefinitionRegistryPostProcessor", beanFactory.getBeanDefinitionCount()));
    }

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        System.out.println(String.format(">>>>>>>>>>>>>>>> {%s} %s", "MyBeanDefinitionRegistryPostProcessor", "postProcessBeanDefinitionRegistry 執行了"));
        System.out.println(String.format(">>>>>>>>>>>>>>>> {%s} bean 的數量 %d", "MyBeanDefinitionRegistryPostProcessor", registry.getBeanDefinitionCount()));
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Cat.class).getBeanDefinition();
        registry.registerBeanDefinition("hello", beanDefinition);
    }

}
2. MyBeanFactoryPostProcessor
@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        System.out.println(String.format("================ {%s} %s", "MyBeanFactoryPostProcessor", "postProcessBeanFactory 執行了"));
        System.out.println(String.format("================ {%s} bean 的數量是 %d", "MyBeanFactoryPostProcessor", beanFactory.getBeanDefinitionCount()));
    }

}
3. ExtensionApplication
public class ExtensionApplication {

    public static void main(String[] args) {
        // >>>>>>>>>>>>>>>> {MyBeanDefinitionRegistryPostProcessor} postProcessBeanDefinitionRegistry 執行了
        // >>>>>>>>>>>>>>>> {MyBeanDefinitionRegistryPostProcessor} bean 的數量 9
        // >>>>>>>>>>>>>>>> {MyBeanDefinitionRegistryPostProcessor} postProcessBeanFactory 執行了
        // >>>>>>>>>>>>>>>> {MyBeanDefinitionRegistryPostProcessor} bean 的數量 10
        // ================ {MyBeanFactoryPostProcessor} postProcessBeanFactory 執行了
        // ================ {MyBeanFactoryPostProcessor} bean 的數量是 10
        // person 構造函數執行了
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        context.close();
    }

}

2. EventListener 事件監聽機制

2.1 使用方式

2.1.1 ApplicationListener

監聽容器中發佈的事件,事件驅動模型開發

監聽 ApplicationEvent 及其子類的事件

2.1.2 @EventListener

可以使用註解簡化開發,原理是通過 EventListenerMethodProcessor 處理器解析方法上的 @EventListener 註解

2.2 環境搭建

代碼已經上傳至 https://github.com/masteryourself-tutorial/tutorial-spring ,詳見 tutorial-spring-framework/tutorial-spring-framework-listener 工程

1. MyApplicationListener
@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        System.out.println("=============== MyApplicationListener 接收到事件:" + event.getClass());
    }

}
2. MyAnnotationListener
@Component
public class MyAnnotationListener {

    @EventListener(classes = {ApplicationEvent.class})
    public void applicationEventListen(ApplicationEvent event) {
        System.out.println("*************** MyAnnotationListener 接收到事件:" + event.getClass());
    }

}
3. ListenerApplication
public class ListenerApplication {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        context.publishEvent(new ApplicationEvent("hello spring annotation") {
        });
        context.close();
        // *************** MyAnnotationListener 接收到事件:class org.springframework.context.event.ContextRefreshedEvent
        // =============== MyApplicationListener 接收到事件:class org.springframework.context.event.ContextRefreshedEvent
        // *************** MyAnnotationListener 接收到事件:class pers.masteryourself.tutorial.spring.framework.listener.ListenerApplication$1
        // =============== MyApplicationListener 接收到事件:class pers.masteryourself.tutorial.spring.framework.listener.ListenerApplication$1
        // *************** MyAnnotationListener 接收到事件:class org.springframework.context.event.ContextClosedEvent
        // =============== MyApplicationListener 接收到事件:class org.springframework.context.event.ContextClosedEvent
    }

}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章