1. 程式人生 > >spring註解開發-擴展原理(源碼)

spring註解開發-擴展原理(源碼)

對象初始化 etsec manager stat 每一個 nis sco nap action

1.BeanFactoryPostProcessor

BeanPostProcessor:bean後置處理器,bean創建對象初始化前後進行攔截工作的;

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

BeanFactoryPostProcessor原理:

1)IOC容器創建對象

2)調用AbstractApplicationContext的refresh()方法;

3)調用AbstractApplicationContext的invokeBeanFactoryPostProcessors(beanFactory)方法,然後調用PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors()方法

如何找到所有的BeanFactoryPostProcessor並執行他們的方法;

1)、直接在BeanFactory中找到所有類型是BeanFactoryPostProcessor的組件,並執行他們的方法

2)、在初始化創建其他組件前面執行

2.BeanDefinitionRegistryPostProcessor

它是BeanFactoryPostProcessor的子接口;在所有bean定義信息將要被加載,bean實例還未創建的時候觸發;

所以它優先於BeanFactoryPostProcessor執行;利用BeanDefinitionRegistryPostProcessor可以給容器中再額外添加一些組件;

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

BeanDefinitionRegistryPostProcessor原理:

1)IOC容器創建對象

2)調用AbstractApplicationContext的refresh()方法中的invokeBeanFactoryPostProcessors(beanFactory);

3)從容器中獲取到所有的BeanDefinitionRegistryPostProcessor組件。

//PostProcessorRegistrationDelegate.class
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

3.1)調用invokeBeanDefinitionRegistryPostProcessors依次觸發所有的postProcessBeanDefinitionRegistry()方法

//PostProcessorRegistrationDelegate.class
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
        Iterator var2 = postProcessors.iterator();
        while(var2.hasNext()) {
            BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }

    }

3.2)再來觸發BeanFactoryPostProcessor的postProcessBeanFactory()方法;

//PostProcessorRegistrationDelegate.class
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
        Iterator var2 = postProcessors.iterator();

        while(var2.hasNext()) {
            BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var2.next();
            postProcessor.postProcessBeanFactory(beanFactory);
        }

    }

4)再來從容器中找到BeanFactoryPostProcessor組件;然後依次觸發postProcessBeanFactory()方法

//PostProcessorRegistrationDelegate.class
private static void invokeBeanFactoryPostProcessors(
            Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {

        for (BeanFactoryPostProcessor postProcessor : postProcessors) {
            postProcessor.postProcessBeanFactory(beanFactory);
        }
    }

3.ApplicationListener

public interface ApplicationListener<E extends ApplicationEvent>

監聽 ApplicationEvent 及其下面的子事件;

實現步驟:

1)寫一個監聽器(ApplicationListener實現類)來監聽某個事件(ApplicationEvent及其子類)

@Component
public class MyApplicationListener implements ApplicationListener<ApplicationEvent> {

2)把監聽器加入到容器; @Component

3)只要容器中有相關事件的發布,我們就能監聽到這個事件;
ContextRefreshedEvent:容器刷新完成(所有bean都完全創建)會發布這個事件;
ContextClosedEvent:關閉容器會發布這個事件;

4)、發布一個事件:applicationContext.publishEvent();

applicationContext.publishEvent(new ApplicationEvent(new String("發布事件")) {
        });

事件原理:

1)ContextRefreshedEvent事件:

1.1)容器創建對象:refresh();

1.2)finishRefresh();容器刷新完成會發布ContextRefreshedEvent事件

//AbstractApplicationContext.class
publishEvent(new ContextRefreshedEvent(this));

2)自己發布事件;

3)容器關閉會發布ContextClosedEvent;

【發布事件】

publishEvent(new ContextRefreshedEvent(this));

1)獲取事件的多播器(派發器):getApplicationEventMulticaster()

2)multicastEvent派發事件(原理見下);

3)獲取到所有的ApplicationListener【原理見下】;

for (final ApplicationListener<?> listener : getApplicationListeners(event, type)) {

3.1)、如果有Executor,可以支持使用Executor進行異步派發;

Executor executor = getTaskExecutor();

3.2)、否則,同步的方式直接執行listener方法;invokeListener(listener,event);拿到listener回調onApplicationEvent方法;

【事件多播器(派發器)】

1.1)容器創建對象:refresh();

1.2)在refresh中調用initApplicationEventMulticaster();初始化applicationEventMulticaster

1.2.1)先去容器中找有沒有id=“applicationEventMulticaster”的組件;

1.2.2)如果沒有this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);並且加入到容器中,我們就可以在其他組件要派發事件時候,自動註入這個applicationEventMulticaster;

【容器中有哪些監聽器】

1)容器創建對象:refresh();

2)registerListeners();從容器中拿到所有的監聽器,把他們註冊到applicationEventMulticaster中;

String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
//將listener註冊到ApplicationEventMulticaster中
   getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

註解實現監聽

@EventListener

//可以寫多個
@EventListener(classes={ApplicationEvent.class})
public void listen(ApplicationEvent event){
        System.out.println("UserService監聽事件:"+event);
    }

@EventListener原理:
使用EventListenerMethodProcessor處理器來解析方法上的@EventListener;

SmartInitializingSingleton 原理:

1)ioc容器創建對象並refresh();

2)finishBeanFactoryInitialization(beanFactory);調用preInstantiateSingletons,初始化剩下的單實例bean;

2.1)先創建所有的單實例bean;getBean();

//DefaultListableBeanFactory implement ConfigurableListableBeanFactory 
//實現了方法preInstantiateSingletons
for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
                    boolean isEagerInit;
                    if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                        isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
                            @Override
                            public Boolean run() {
                                return ((SmartFactoryBean<?>) factory).isEagerInit();
                            }
                        }, getAccessControlContext());
                    }
                    else {
                        isEagerInit = (factory instanceof SmartFactoryBean &&
                                ((SmartFactoryBean<?>) factory).isEagerInit());
                    }
                    if (isEagerInit) {
                        getBean(beanName);
                    }
                }
                else {
                    getBean(beanName);
                }
            }
        }

2.2)獲取所有創建好的單實例bean,判斷是否是SmartInitializingSingleton類型的;如果是就調用afterSingletonsInstantiated();

//DefaultListableBeanFactory implement ConfigurableListableBeanFactory 
//實現了方法preInstantiateSingletons
for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged(new PrivilegedAction<Object>() {
                        @Override
                        public Object run() {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }

3)調用EventListenerMethodProcessor實現的 SmartInitializingSingleton接口的afterSingletonsInstantiated方法

for (Method method : annotatedMethods.keySet()) {
                    for (EventListenerFactory factory : factories) {
                        if (factory.supportsMethod(method)) {
                            Method methodToUse = AopUtils.selectInvocableMethod(
                                    method, this.applicationContext.getType(beanName));
                            ApplicationListener<?> applicationListener =
                                    factory.createApplicationListener(beanName, targetType, methodToUse);
                            if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                                ((ApplicationListenerMethodAdapter) applicationListener)
                                        .init(this.applicationContext, this.evaluator);
                            }
                            this.applicationContext.addApplicationListener(applicationListener);
                            break;
                        }
                    }

spring註解開發-擴展原理(源碼)