Gradle中ListenerManager的初始化流程

接口实现
    public void addListener(Object listener) {               //interface 1
        synchronized (lock) {
            if (allListeners.add(listener)) {
                for (BroadcastDispatch<?> broadcaster : dispatchers.values()) {
                    maybeAddToDispatcher(broadcaster, listener);
                }
            }
        }
    }
	------------------------------------------------------------------------------
	public void useLogger(Object logger) {					//interface 2
        synchronized (lock) {
            if (allLoggers.add(logger)) {
                for (LoggerDispatch dispatch : loggers.values()) {
                    dispatch.maybeSetLogger(logger);
                }
            }
        }
    }
	--------------------------------------------------------------------------------
	public <T> T getBroadcaster(Class<T> listenerClass) {		//interface 3
        return getBroadcasterInternal(listenerClass).getSource();
    }

	private <T> ListenerBroadcast<T> getBroadcasterInternal(Class<T> listenerClass) {
        synchronized (lock) {
            ListenerBroadcast<T> broadcaster = broadcasters.get(listenerClass);
            if (broadcaster == null) {
                broadcaster = new ListenerBroadcast<T>(listenerClass);

				//Add dispatch object into broadcaster's handlers queue.
                broadcaster.add(getLogger(listenerClass));
                broadcaster.add(getDispatcher(listenerClass));
                if (parent != null) {
                    broadcaster.add(parent.getDispatcher(listenerClass));
                }
                broadcasters.put(listenerClass, broadcaster);
            }

            return broadcaster;
        }
    }

	private LoggerDispatch getLogger(Class<?> listenerClass) {
        synchronized (lock) {
            LoggerDispatch dispatch = loggers.get(listenerClass);
            if (dispatch == null) {
                dispatch = new LoggerDispatch(listenerClass, parent == null ? null : parent.getLogger(listenerClass));
                for (Object logger : allLoggers) {
                    dispatch.maybeSetLogger(logger);
                }
                loggers.put(listenerClass, dispatch);
            }
            return dispatch;
        }
    }

	    private LoggerDispatch(Class<?> type, LoggerDispatch parentDispatch) {
            this.type = type;
            this.dispatch = parentDispatch;
        }

//1.In  org.gradle.initialization DefaultGradleLauncherFactory.java
//The constructor of DefaultGradleLauncherFactory

	    // Register default loggers
        ListenerManager listenerManager = sharedServices.get(ListenerManager.class);
        buildProgressLogger = new BuildProgressLogger(sharedServices.get(ProgressLoggerFactory.class));

		//interface 1, 'allListeners' is empty, and only add item to Set<>, do nothing else.
        listenerManager.addListener(new BuildProgressFilter(buildProgressLogger));
		//interface 2, 'allLoggers' is empty, and only add item to Set<>, do nothing else
        listenerManager.useLogger(new DependencyResolutionLogger(sharedServices.get(ProgressLoggerFactory.class)));

//2. Same package, DefaultGradleLauncherFactory.java
//doNewInstance function

		//小插曲,调用了一下函数 from BuildScopeServies::createListenerManager
		/*
		public ListenerManager createChild() {
			return new DefaultListenerManager(this);
		}
		*/
		//Then the 'listenerManager' is a totally new object,
		//and the one before becomes its 'parent'

		ListenerManager listenerManager = serviceRegistry.get(ListenerManager.class);
        //this hooks up the ListenerManager and LoggingConfigurer so you can call Gradle.addListener() with a StandardOutputListener.
		//Interface 3, 'broadcasters' map is empty , then new an ListenerBroadcast object 'broadcaster'
		//In 'getLogger', the 'loggers' is empty,
		//in new LoggerDispatch, it will call parent.getLogger first (递归), parent's loggers is empty
		//so parent listenerManager will return a LoggerDispatch object, with 'dispatch' null, and put it into parent's loggers queue.
		//To son's turn, the new LoggerDispatch will be an object with 'dispatch' point to the object returned from parent.

		//Parent.loggers.values constains a value of DefaultListenerManager$LoggerDispatch (id=196), its dispatch is null
		//this.loggers.values constains value of DefaultListenerManager$LoggerDispatch, it's dispatch var member is also a DefaultListenerManager$LoggerDispatch
		//with id=196, so the parent/child chain is made
        loggingManager.addStandardOutputListener(listenerManager.getBroadcaster(StandardOutputListener.class));

时间: 2024-08-16 15:21:10

Gradle中ListenerManager的初始化流程的相关文章

Shiro权限管理框架(三):Shiro中权限过滤器的初始化流程和实现原理

本篇是Shiro系列第三篇,Shiro中的过滤器初始化流程和实现原理.Shiro基于URL的权限控制是通过Filter实现的,本篇从我们注入的ShiroFilterFactoryBean开始入手,翻看源码追寻Shiro中的过滤器的实现原理. 初始化流程 ShiroFilterFactoryBean实现了FactoryBean接口,那么Spring在初始化的时候必然会调用ShiroFilterFactoryBean的getObject()获取实例,而ShiroFilterFactoryBean也在

SylixOS CAN总线初始化流程解析

概述 本文档是在AT91SAM9X25平台上进行SylixOS CAN总线驱动开发时,对CAN总线初始化流程的分析. 适用于正在学习CAN总线开发的技术工程师. 技术实现 CAN总线的初始化流程可以分成两个部分: 一部分是CAN总线通道资源初始化,主要工作是对通道相关的管脚和中断以及总线编程时需要的时钟等资源的初始化:另一部分是CAN总线的硬件初始化,主要工作是对总线的波特率的设置.接收和发送数据邮箱(相当于缓存区)的初始化以及接收中断和错误中断的使能. CAN总线通道资源初始化 在AT91SA

SpringMVC源码剖析(三)- DispatcherServlet的初始化流程

在我们第一次学Servlet编程,学Java Web的时候,还没有那么多框架.我们开发一个简单的功能要做的事情很简单,就是继承HttpServlet,根据需要重写一下doGet,doPost方法,跳转到我们定义好的jsp页面.Servlet类编写完之后在web.xml里注册这个Servlet类. 除此之外,没有其他了.我们启动web服务器,在浏览器中输入地址,就可以看到浏览器上输出我们写好的页面.为了更好的理解上面这个过程,你需要学习关于Servlet生命周期的三个阶段,就是所谓的“init-s

Nginx 中 HTTP模块初始化

概述 在前面的文章< Nginx 配置解析>简单讲解了通用模块的配置项解析,并且大概讲解了HTTP 模块的配置项解析过程,本文更具体的分析 HTTP 模块的初始化过程.HTTP 模块初始化过程主要有:上下文结构初始化.配置项解析.配置项合并.server 相关端口设置. HTTP 模块接口 ngx_http_module_t 结构体 在 Nginx 中,结构体 ngx_module_t 是 Nginx 模块最基本的接口.对于每一种不同类型的模块,都有一个具体的结构体来描述这一类模块的通用接口.

20. Gradle编译其他应用代码流程(七) - 守护进程编译

上一篇博客 18. Gradle编译其他应用代码流程(六) - 执行Task过程 一. 守护进程的作用 守护进程就是一个用来构建的其他进程. 从前几篇文章我们知道gradle编译的时候会加载各种所需要的Jar,加载这些Jar是需要时间的. 如果我们之前有守护进程编译过其他程序,而这个进程没有被kill掉,那么是可以重用这个守护进程的. 二. 选择守护进程编译 选择守护进程编译的策略是 如果守护进程存在,那么就使用守护进程编译. 否则,如果可以在当前进程编译,那么就在当前进程编译. 否则,启动新的

Android 6.0 SIM卡初始化流程

本文主要讲述Android 6.0 SIM卡初始化流程,这个过程也涉及到UICC框架的初始化,UICC(Universal Integrated Circuit Card)的架构图如下: /** * This class is responsible for keeping all knowledge about * Universal Integrated Circuit Card (UICC), also know as SIM's, * in the system. It is also

【开源】OSharp3.3框架解说系列(7.1):初始化流程概述

本文已同步到系列目录:OSharp快速开发框架解说系列 框架初始化 相对于OSharp 3.0,3.3版本最大的更新,就是从框架级别定义了初始化流程,对初始化功能进行了抽象与封装,不依赖于第三方实现,第三方实现仅作为可替换的服务实现方案存在. 例如,依赖注入功能中,接口与其实现类的映射配置,对象容器的构建,对象的解析获取,都将通过框架定义的API来完成,而Autofac,仅作为这些功能的实现方存在,如果不想使用Autofac,则可以很方便的切换成别的IoC组件. 具体的初始化功能是怎样抽象与定义

Raid1源代码分析--初始化流程

初始化流程代码量比较少,也比较简单.主要是run函数.(我阅读的代码的linux内核版本是2.6.32.61) 四.初始化流程分析 run函数顾名思义,很简单这就是在RAID1开始运行时调用,进行一些初始化的操作.主要是对RAID1中的conf进行初始化.run函数在md.c的do_md_run中被调用.   run函数的具体流程 0.传入参数mddev就是指RAID1所处的MD设备. 1.  定义相关变量. 1.1  定义conf指针,类型为raid1_private_data_s,是raid

Spring Core Container 源码分析三:Spring Beans 初始化流程分析

前言 本文是笔者所著的 Spring Core Container 源码分析系列之一: 本篇文章主要试图梳理出 Spring Beans 的初始化主流程和相关核心代码逻辑: 本文转载自本人的私人博客,伤神的博客: http://www.shangyang.me/2017/04/01/spring-core-container-sourcecode-analysis-beans-instantiating-process/ 本文为作者的原创作品,转载需注明出处: 源码分析环境搭建 参考 Sprin