【记一次有关定时任务的问题】

摘要:
所涉及的内容包括定时任务、httpClient的HTML获取和Jsoup的代码分割。获取上次更新数据时更新的第一条数据。在查询之后,从数据库中获得的最后更新的数据也被传输到爬虫方法,因此爬虫方法不涉及任何数据库操作。事实上,此时每个网站都对应一个类,但排定的任务只能在方法前面标识,每个方法不能有排定的任务。这三个类之间的关系依次继承。事实上,这个计时任务的架构已经完成。但实际上,这是spring对控制和依赖注入的反转。
背景

最近写的内容是,用java爬下来几个学校网站的招聘信息数据。涉及到的内容有定时任务、httpClient进行html抓取,Jsoup进行代码的分割。其他的就只是爬取数据时的Document分析。


最初的代码架构设计

也不算什么架构设计,但也确实是第一次去思考代码的简洁、可复用、美观。也是想了很久。

起初要实现的是,在一个方法去进行定时任务。对代码通过功能进行分块。爬虫的代码统一放到一起。保存的代码统一到一起。在我起初的想法中,想的很复杂。

  1.  获取上一次更新数据时更新的第一条数据。
  2. 通过HttpClient进行抓取招聘信息第一页源码。
  3. 通过jsoup对抓下来的源码进行截取。
  4. 在截取所需要的数据时,最后肯定是将招聘信息的那个表格拿到,通过for循环遍历出来,每条数据都需要去判断是否是新数据。
  5. 然后进行判断是否有下一页,如果有下一页,判断下一页网址和当前页面网址是否相同。如果相同 表示当前页面就已经是下一页。

在我的想法中,爬虫的代码是循环套着循环。代码的耦合性太高,不好拆分,别人也不易观看。可我在当前的思路中又的确拆分不出来一些思路。如果爬虫的部分拆开?首先爬虫代码无法复用,通常是一个网站对应一个爬取数据的方式。那把爬虫代码拆开主要就是代码的可读性。那爬的部分是一个循环套住一个循环。如果我把里面的循环重构成一个新的方法,那怎么才能通过返回值来执行我什么时候才能跳出循环。而且这样没太大意义。而且我的思路是,判断完是否是新数据就进行保存到数据库,如果重构之后,保存到数据库这部分代码其实和数据的爬取没太大关系。也是应该摘出来的。


最终的代码架构设计

最后经过讨论,决定将爬虫部分代码整体摘出来,且保存数据部分不在爬虫时执行。当时我想的跳出循环问题困扰了我很久,但其实摘出来以后。跳出循环只要return,就可以结束这个方法的调用。之前困扰我,是因为我打算用爬虫作为主要方法去调用别的方法。而现在,是别的方法调用爬虫的方法,所以要结束循环,只需要直接return就好了。不需要再进行连接数据库,是因为返回值是一个装好了数据的List,调用爬虫方法得到新数据的List之后进行统一保存。而那从数据库中获取上一次更新的数据,也是查询完传到 爬虫方法中,所以爬虫的方法中不涉及任何有关的数据库操作。和之前的设想相符合。

那其实此时是每一个网站对应一个类,但定时任务(在这里使用的是@Scheduled)只能标识在方法前,总不能每个方法都来个定时任务。所以必不可免的需要 -----有一个方法把这些调动爬虫的方法归拢起来。

那此时的架构就变得更加的清晰。我只需要三个类。【记一次有关定时任务的问题】第1张

这三个类之间的关系是依次继承的关系。那其实这个定时任务的架构就完成了。


设计架构时出现的问题

在SaveSpiderDate去掉用SpiderDate时,怎么去掉用其中的方法?

我下意识就去new。但总是报错,说是空指针。空指针指向的位置是 调用数据库取值时出现的错误。

【记一次有关定时任务的问题】第2张

报错结果是if括号中的内容,此方法是没有问题的,那只能出现Autowired时,没有注入进来。当时想了好久,也不知道该怎么解决。但其实是 spring的控制反转、依赖注入的问题。因为爬虫和定时任务不算是Controller包含的,所以用的注解是@Component,就被混淆视听了。但其实和controller没什么本质的区别,换而言之,Controller标注的类 目的就是Spring帮忙把这个类创建好,这个类中涉及的其他的类 比如@Autowired的部分 都会被注入进来。而如果 new 出来的对象中,像@Autowired 这类的Spring的注解  涉及到的类就不会自动注入。

那不能new,需要什么方式来得到这个对象。

 继承是一种方式

@Autowired也是一种方式

免责声明:文章转载自《【记一次有关定时任务的问题】》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Google Breakpad之七,android平台简明用法asterisk 常用命令下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Sql Server2008 中的SQL Server Management Studio(SSMS) (转)

Management Studio首次出现在MSSQL2005中,到MSSQL2008中已经成为了一个更成功的产品。其中在SSMS2008中最重要的特性如下: 1.活动监视器 2.对象资源管理器详细信息 3.搜索 4.查询编辑器之IntelliSense 5.查询编辑器之T-SQL调试 这些只是部分关键功能,其他的功能你可以亲自使用SSMS来发现,...

IIS连接oralce数据库时 提示“System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本”

最近由WindowsXP换到了Windows2003系统(Windows 7),Oracle也由原来的8i换到了9i。给客户发布了一个web系统,部署在本机IIS上测试的时候出现了“取不到缓存数据”的自定义异常,经过跟踪找到原因,在连接数据库时,出现“System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本...

SQLSERVER查询数据库文件大小

SQLSERVER一个库的文件分为数据文件(行数据)和日志文件两个文件,详情可以在数据库的属性->文件中查看。 在资源管理器中打开文件所在路径可以直接看到这两个文件 但是,大多数时候我们的数据库安装在远程服务器上,在不远程的情况下,可以使用如下SQL语句: 1、查询各个磁盘分区的剩余空间(就是C盘还有多少空间,D盘还有多少...): Exec m...

老技术记录-C#+SqlServer使用SqlDependency监听数据库表变化

开发环境: .net / C# (.net core理论上也可以) 数据库:MS SQL Server 2005 以上 (我用的sqlserver2012) 功能:SqlDependency提供了一种机制,当被监听的数据库中的数据发生变化时,SqlDependency会自动触发OnChange事件来通知应用程序,从而达到让应用程序实时更新数据(或缓存)的目...

Oracle表中一行记录被锁(行锁,表锁,死锁)

表现形式:可以向表里面save新数据,但是无法跟新某一条数据,update的时候就一直在等待。 Oracle锁表查询和解锁方法 数据库操作语句的分类DDL:数据库模式定义语言,关键字:createDML:数据操纵语言,关键字:Insert、delete、updateDCL:数据库控制语言 ,关键字:grant、removeDQL:数据库查询语言,关键字:s...

MySQL数据库导入导出详解[转发]

1. 概述 MySQL数据库的导入,有两种方法: 1) 先导出数据库SQL脚本,再导入; 2) 直接拷贝数据库目录和文件。 在不同操作系统或MySQL版本情况下,直接拷贝文件的方法可能会有不兼容的情况发生。 所以一般推荐用SQL脚本形式导入。下面分别介绍两种方法。 2. 方法一 SQL脚本形式 操作步骤如下: 2.1. 导出SQL脚本 在原数据库服务器上,...