zoukankan      html  css  js  c++  java
  • spring注解开发-扩展原理(源码)

    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;
    						}
    					}
    
  • 相关阅读:
    spark 读取mongodb失败,报executor time out 和GC overhead limit exceeded 异常
    在zepplin 使用spark sql 查询mongodb的数据
    Unable to query from Mongodb from Zeppelin using spark
    spark 与zepplin 版本兼容
    kafka 新旧消费者的区别
    kafka 新生产者发送消息流程
    spark ui acl 不生效的问题分析
    python中if __name__ == '__main__': 的解析
    深入C++的new
    NSSplitView
  • 原文地址:https://www.cnblogs.com/ntbww93/p/10104996.html
Copyright © 2011-2022 走看看