设计满足开闭原则的策略模式
开闭原则是说不修改原有代码的基础上,对于新增加的功能采用实现接口的方法即可实现
策略模式将对象的行为抽象为一个通用的方法,不同的对象实现同一个方法进行重写,可以减少复杂的if else的出现
代码如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ip</groupId>
<artifactId>ip-service</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<skipTests>true</skipTests>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!--客户端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--tomcat容器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--添加fastjson依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.7</version>
</dependency>
<!--lombok依赖-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!--springboot整合mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<!-- 热部署模块 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 这个需要为 true 热部署才有效 -->
</dependency>
<!--java爬虫需要的jar包-->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.12.2</version>
</dependency>
<!--判断空的用法 -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--时间日期工具类-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.10.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
<!--RateLimiter的底层是基于令牌桶算法来实现的,来自谷歌的Guava包中-->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>org.lionsoul</groupId>
<artifactId>ip2region</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<finalName>server</finalName>
</build>
</project>
package com.ip.controller.front;
import com.ip.bean.CrawlerDTO;
import com.ip.config.SpringBeanUtil;
import com.ip.handle.strategy.CrawlerHandleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* @author yourheart
* @Description
* @create 2022-04-26 21:40
*/
@Controller
@RequestMapping("/crawler")
@Slf4j
public class CrawlerController {
/**
* 自动获取网页的名称
* @param crawlerDTO
* @return
*/
@PostMapping("/crawlerAddress")
@ResponseBody
public CrawlerDTO crawlerAddress(@RequestBody CrawlerDTO crawlerDTO){
log.info("【自动获取网页的名称】入参:{}",crawlerDTO);
String serverName=crawlerDTO.getUrlDatasource()+"_crawler";
CrawlerHandleStrategy bean = SpringBeanUtil.getBean(serverName, CrawlerHandleStrategy.class);
CrawlerDTO crawlerDto = bean.getCrawlerDto(crawlerDTO);
return crawlerDto;
}
}
package com.ip.config;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/12/8 18:42
*/
@Component
public class SpringBeanUtil implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (context==null){
context=applicationContext;
}
}
public static ApplicationContext getContext(){
return context;
}
/**
* 通过name找到对应的实例
* @param name
* @return
*/
public static Object getBean(String name){
return getContext().getBean(name);
}
/**
* 通过class获取实例
* @param tClass
* @param <T>
* @return
*/
public static <T> T getBean(Class<T> tClass){
return getContext().getBean(tClass);
}
public static <T> T getBean(String name,Class<T> tClass){
T bean = getContext().getBean(name, tClass);
return bean;
}
}
package com.ip.handle.strategy;
import com.ip.bean.CrawlerDTO;
/**
* @Description: 处理爬虫的策略接口
* @Author: Yourheart
* @Create: 2022/12/8 15:15
*/
public interface CrawlerHandleStrategy {
/**
* 通过爬虫获取网页地址的名称
* @param crawlerDTO
* @return
*/
CrawlerDTO getCrawlerDto(CrawlerDTO crawlerDTO);
}
package com.ip.handle.strategy.impl;
import com.ip.bean.CrawlerDTO;
import com.ip.handle.strategy.CrawlerHandleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/12/8 15:38
*/
@Slf4j
@Service("default_crawler")
public class DefaultCrawlerHandleStrategy implements CrawlerHandleStrategy {
/**
* 通过爬虫获取网页地址的名称
*
* @param crawlerDTO
* @return
*/
@Override
public CrawlerDTO getCrawlerDto(CrawlerDTO crawlerDTO) {
log.info("使用默认方法获取网页地址.....");
return null;
}
}
package com.ip.handle.strategy.impl;
import com.ip.bean.CrawlerDTO;
import com.ip.handle.strategy.CrawlerHandleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/12/8 15:37
*/
@Slf4j
@Service("jianshu_crawler")
public class JianShuCrawlerHandleStrategy implements CrawlerHandleStrategy {
/**
* 通过爬虫获取网页地址的名称
*
* @param crawlerDTO
* @return
*/
@Override
public CrawlerDTO getCrawlerDto(CrawlerDTO crawlerDTO) {
log.info("爬虫简书的地址...");
return null;
}
}
package com.ip.handle.strategy.impl;
import com.ip.bean.CrawlerDTO;
import com.ip.handle.strategy.CrawlerHandleStrategy;
import lombok.extern.slf4j.Slf4j;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.util.Arrays;
/**
* @Description:
* @Author: Yourheart
* @Create: 2022/12/8 15:37
*/
@Slf4j
@Service("weixin_crawler")
public class WeiXinCrawlerHandleStrategy implements CrawlerHandleStrategy {
/**
* 通过爬虫获取网页地址的名称
*
* @param crawlerDTO
* @return
*/
@Override
public CrawlerDTO getCrawlerDto(CrawlerDTO crawlerDTO) {
log.info("爬虫微信的地址...");
String url = crawlerDTO.getUrl();
try {
Document doc = Jsoup.connect(url).get();
Elements select = doc.select("meta[property=twitter:title]");
StringBuilder stringBuilder=new StringBuilder();
for (Element element : select) {
String string = element.toString();
string = string.replace("<", "");
string = string.replace(">", "");
string = string.replace("\"", "");
String[] split = string.split("=");
Arrays.stream(split).forEach(a->{
log.info("a:{}",a);
});
stringBuilder.append(split[split.length - 1]);
}
} catch (IOException e) {
log.error("【微信爬虫失败】:{}",e);
}
return null;
}
}
浙公网安备 33010602011771号