Heritrix 3.1.0 源码解析(十一)
上文分析了Heritrix3.1.0系统是怎么添加CrawlURI curi对象的,那么在系统初始化的时候,是怎么载入CrawlURI curi种子的呢?
我们回顾前面的文章,在我们执行采集任务的launch指令的时候,实际会调用CrawlController对象的void requestCrawlStart()方法
/** * Operator requested crawl begin*/public void requestCrawlStart() {hasStarted = true; sendCrawlStateChangeEvent(State.PREPARING, CrawlStatus.PREPARING);if(recoveryCheckpoint==null) {// only announce (trigger scheduling of) seeds// when doing a cold (non-recovery) start getSeeds().announceSeeds();}setupToePool();// A proper exit will change this value.this.sExit = CrawlStatus.FINISHED_ABNORMAL;if (getPauseAtStart()) {// frontier is already paused unless started, so just // 'complete'/ack pause completePause();} else {getFrontier().run();}}
继续调用getSeeds().announceSeeds()方法,这里的getSeeds()真实对象是TextSeedModule(spring自动注入的),然后调用它的void announceSeeds()方法
/*** Announce all seeds from configured source to SeedListeners * (including nonseed lines mixed in). * @see org.archive.modules.seeds.SeedModule#announceSeeds()*/public void announceSeeds() {if(getBlockAwaitingSeedLines()>-1) {final CountDownLatch latch = new CountDownLatch(getBlockAwaitingSeedLines());new Thread(){@Overridepublic void run() {announceSeeds(latch); while(latch.getCount()>0) {latch.countDown();}}}.start();try {latch.await();} catch (InterruptedException e) {// do nothing } } else {announceSeeds(null); }}
上面方法中if后面的CountDownLatch latch是线程计数,else后面是null,继续调用void announceSeeds(CountDownLatch latchOrNull)方法
protected void announceSeeds(CountDownLatch latchOrNull) {BufferedReader reader = new BufferedReader(textSource.obtainReader()); try {announceSeedsFromReader(reader,latchOrNull); } finally {IOUtils.closeQuietly(reader);}}
首先获取ReadSource textSource(org.archive.spring.ConfigString)的Reader(StringReader),然后调用void announceSeedsFromReader(BufferedReader reader, CountDownLatch latchOrNull)方法
/*** Announce all seeds (and nonseed possible-directive lines) from* the given Reader* @param reader source of seed/directive lines* @param latchOrNull if non-null, sent countDown after each line, allowing * another thread to proceed after a configurable number of lines processed*/protected void announceSeedsFromReader(BufferedReader reader, CountDownLatch latchOrNull) {String s;Iterator<String> iter = new RegexLineIterator(new LineReadingIterator(reader),RegexLineIterator.COMMENT_LINE,RegexLineIterator.NONWHITESPACE_ENTRY_TRAILING_COMMENT,RegexLineIterator.ENTRY);int count = 0; while (iter.hasNext()) {s = (String) iter.next();if(Character.isLetterOrDigit(s.charAt(0))) {// consider a likely URI seedLine(s);count++;if(count%20000==0) {System.runFinalization();}} else {// report just in case it's a useful directive nonseedLine(s);}if(latchOrNull!=null) {latchOrNull.countDown(); }}publishConcludedSeedBatch(); }
迭代url字符串并调用void seedLine(String uri)方法
/*** Handle a read line that is probably a seed.* * @param uri String seed-containing line*/protected void seedLine(String uri) {if (!uri.matches("[a-zA-Z][\\w+\\-]+:.*")) { // Rfc2396 s3.1 scheme,// minus '.'// Does not begin with scheme, so try http:// uri = "http://" + uri;}try {UURI uuri = UURIFactory.getInstance(uri);CrawlURI curi = new CrawlURI(uuri);curi.setSeed(true);curi.setSchedulingDirective(SchedulingConstants.MEDIUM);if (getSourceTagSeeds()) {curi.setSourceTag(curi.toString());}publishAddedSeed(curi);} catch (URIException e) {// try as nonseed line as fallback nonseedLine(uri);}}
最后调用父类SeedModule的void publishAddedSeed(CrawlURI curi)方法(observer模式)
protected void publishAddedSeed(CrawlURI curi) {for (SeedListener l: seedListeners) {l.addedSeed(curi);}}
BdbFrontier类间接实现了SeedListener接口(AbstractFrontier抽象类void addedSeed(CrawlURI puri)方法)
/*** When notified of a seed via the SeedListener interface, * schedule it.* * @see org.archive.modules.seeds.SeedListener#addedSeed(org.archive.modules.CrawlURI)*/public void addedSeed(CrawlURI puri) {schedule(puri);}
---------------------------------------------------------------------------
本系列Heritrix 3.1.0 源码解析系本人原创
转载请注明出处 博客园 刺猬的温驯
本文链接 http://www.cnblogs.com/chenying99/archive/2013/04/20/3031924.html
Heritrix 3.1.0 源码解析(十一)相关推荐
- Heritrix 3.1.0 源码解析(八)
本文接着分析存储CrawlURI curi的队列容器,最重要的是BdbWorkQueue类及BdbMultipleWorkQueues类 BdbWorkQueue类继承自抽象类WorkQueue,抽象 ...
- Heritrix 3.1.0 源码解析(六)
本文分析BdbFrontier对象的相关状态和方法 BdbFrontier类继承自WorkQueueFrontier类 WorkQueueFrontier类继承自AbstractFrontier类 ...
- Heritrix 3.1.0 源码解析(三十四)
本文主要分析FetchFTP处理器,该处理器用于ftp文件的下载,该处理器的实现是通过封装commons-net-2.0.jar组件来实现ftp文件下载 在FetchFTP处理器里面定义了内部类Soc ...
- Heritrix 3.1.0 源码解析(十四)
我在分析BdbFrontier对象的void schedule(CrawlURI caURI).CrawlURI next() .void finished(CrawlURI cURI)方法是,其实还 ...
- solrlucene3.6.0源码解析(三)
solr索引操作(包括新增 更新 删除 提交 合并等)相关UML图如下 从上面的类图我们可以发现,其中体现了工厂方法模式及责任链模式的运用 UpdateRequestProcessor相当于责任链模式 ...
- 锚框、交并比和非极大值抑制(tf2.0源码解析)
锚框.交并比和非极大值抑制(tf2.0源码解析) 文章目录 锚框.交并比和非极大值抑制(tf2.0源码解析) 一.锚框生成 1.锚框的宽高 2.锚框的个数 3.注意点(★★★) 4.tf2.0代码 二 ...
- 基于8.0源码解析:startService 启动过程
基于8.0源码解析:startService 启动过程 首先看一张startService的图,心里有个大概的预估,跟Activity启动流程比,Service的启动稍微简单点,并且我把Service ...
- Android Glide 3.7.0 源码解析(八) , RecyclableBufferedInputStream 的 mark/reset 实现
个人博客传送门 一.mark / reset 的作用 Android Glide 3.7.0 源码解析(七) , 细说图形变换和解码有提到过RecyclableBufferedInputStream ...
- Vue2.0源码解析——编译原理
Vue2.0源码解析--编译原理 前言:本篇文章主要对Vue2.0源码的编译原理进行一个粗浅的分析,其中涉及到正则.高阶函数等知识点,对js的考察是非常的深的,因此我们来好好啃一下这个编译原理的部分. ...
最新文章
- SOAPUI请求及mockservice 使用
- Objective C内存管理之理解autorelease------面试题
- DIKW体系(Data-Information-Knowlege-Wisdom)
- matlab对图像进行增强,利用matlab对图像进行增强处理.doc
- 3项目在ie11浏览器打不开_Chrome/Safari都输了:新Edge浏览器率先实现100%支持HTML5...
- 你刚才淘宝上买衣服---具体分析技术工艺(淘宝页面显示处理的页面)
- 看看自己08年的基金是否能赚钱
- 【MSDN】正则表达式介绍
- Python字典操作
- [USACO13FEB]Milk Scheduling【拓扑序】
- 使用redis作为缓存,数据还需要存入数据库中吗?
- python和go哪个就业前景好_Python和Java就业前景对比
- java私有的构造函数_Java 私有构造函数的使用
- Maxwell原理与应用
- 如何解决电脑横屏问题
- 腾达ac5第三方固件_腾达AC9的刷固件指南
- html表格背景图片格式,CSS常见样式(二)——列表,背景,边框,行高,表格,vertical-align...
- java江湖壹_江湖壹怎么玩 江湖壹玩法攻略
- 【深度访问】Cocos2d-JS精品《航海王启航》:我们是要成为游戏王的团队
- mysql workbench自动备份_MySQL如何自动备份
热门文章
- %hd %d %ld %u ......
- c语言基本字符集ppt,C语言的字符集和保留字知识讲稿.ppt
- MyBatis参数名称解析器-ParamNameResolver解析
- docker下如何进入到容器中
- java多张图片上传安卓,Android Rxjava+Retrofit2 多图片+文字上传
- 数据库安全性相关知识笔记​
- 收集17句经典程序员口头禅
- C#程序集相关的概念
- mvc调用mysql存储过程_使用.NET MVC +EF调用oracle的存储过程
- oracle 11g重新安装配置,Oracle 11g数据库安装和卸载教程