目录:

  • 概述
  • 观察者模式
  • 代理模式

概述:

spring系列中使用了大量的设计模式,而最常见的便是这观察者、代理模式,所以在讲解SpringCloud之前我们先学习下这两个最常见的设计模式。

观察者模式:

java实现了自己的观察者模式 >>> java.util.Observable

1、public synchronized void addObserver(Observer o);添加一个观察者

2、public synchronized void deleteObserver(Observer o);删除一个观察者

3、protected synchronized void setChanged();修改通知标记,使得观察者观察的对象发生变化时能记得得知

4、public void notifyObservers(Object arg) ;通知观察者,被观察这已发生变化

 public class ObserverDemo extends Observable {

     /**
* 通知观察者被观察者已发生变化
*/
public void notifyObserver() {
// 设置变化状态为true >>> 被观察者已发生变化
this.setChanged();
// 将这一变化通知观察者
this.notifyObservers();
} public static void main(String[] args) {
testAddObserver();
testDeleteObserver();
} private static void testAddObserver() {
ObserverDemo observerDemo = new ObserverDemo();
observerDemo.addObserver((o, arg) -> System.err.println("服务列表发生变化1"));
observerDemo.notifyObserver();
} private static void testDeleteObserver() {
ObserverDemo observerDemo = new ObserverDemo();
Observer observer = (o, arg) -> System.err.println("服务列表发生变化2"); observerDemo.addObserver(observer);
observerDemo.notifyObserver();
observerDemo.deleteObserver(observer);
observerDemo.notifyObserver();
}
}

代理模式:

1、静态代理

代理就是将除了自己本身需要做的核心业务外的任务交给代理人来做,如明星将接广告等事情交给经纪人。

 public interface Agent {

     /**
* 拍广告
*/
void advertising();
}
 public class Celebrity implements Agent {

     @Override
public void advertising() {
System.err.println("Celebrity拍广告");
}
}
 public class Celebrity2 implements Agent {

     @Override
public void advertising() {
System.err.println("Celebrity2拍广告");
}
}
 public class ProxyDemo implements Agent {

     private Agent agent;

     public ProxyDemo(Agent agent) {
this.agent = agent;
} @Override
public void advertising() {
before();
agent.advertising();
after();
} private void after() {
System.err.println("after");
} private void before() {
System.err.println("before");
}
} class ProxyClient { public static void main(String[] args) {
Agent agent = new ProxyDemo(new Celebrity());
agent.advertising(); System.out.println("----------------------------"); Agent agent2 = new ProxyDemo(new Celebrity2());
agent2.advertising();
}
}

静态代理的缺点是如果代理对象新代理了一个行为,那么委托对象也需要将新的代理行为重实现一遍,这样非常繁琐且重复。

为什么说静态代理繁琐呢,我们来增加一个行为。

 public interface Agent {
/**
* 拍广告
*/
void advertising(); /**
* 集资
*/
void collectMoney();
}

然后我们修改一下Celebrity、Celebrity2

 public class Celebrity implements Agent {

     @Override
public void advertising() {
System.err.println("Celebrity拍广告");
} @Override
public void collectMoney() {
System.err.println("Celebrity集资");
}
}
 public class Celebrity2 implements Agent {

     @Override
public void advertising() {
System.err.println("Celebrity2拍广告");
} @Override
public void collectMoney() {
System.err.println("Celebrity2集资");
}
}

然后我们看看修改后的ProxyDemo

 public class ProxyDemo implements Agent {

     private Agent agent;

     public ProxyDemo(Agent agent) {
this.agent = agent;
} @Override
public void advertising() {
before();
agent.advertising();
after();
} @Override
public void collectMoney() {
before();
agent.collectMoney();
after();
} private void after() {
System.err.println("after");
} private void before() {
System.err.println("before");
}
} class ProxyClient { public static void main(String[] args) {
Agent agent = new ProxyDemo(new Celebrity());
agent.advertising();
agent.collectMoney(); System.out.println("----------------------------"); Agent agent2 = new ProxyDemo(new Celebrity2());
agent2.advertising();
agent2.collectMoney();
}
}

我们发现仅仅增加一个行为委托类也要实现collectMoney,实现时不仅需要调用agent.collectMoney,还需要调用before和after是不是很麻烦,而接下来要讲的动态代理正是为了解决这一问题。

2、动态代理

动态代理的例子还是和静态代理一样,我们首先将委托类写好。

 public class DynamicProxyDemo implements InvocationHandler {

     private Object target;

     public DynamicProxyDemo(Object target) {
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
after();
Object invoke = method.invoke(target, args);
before();
return invoke;
} private void after() {
System.err.println("after");
} private void before() {
System.err.println("before");
} public Object getProxy() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
}

其中最重要的是InvocationHandler接口和getProxy方法。

此时我们再往Agent增加一个行为,Celebrity、Celebrity2省略

 public interface Agent {
/**
* 拍广告
*/
void advertising(); /**
* 集资
*/
void collectMoney(); /**
* 安排行程
*/
void travelArrangements();
}

然后我们发现,DynamicProxyDemo不需要再实现新的行为了,这都归功于InvocationHandler !!!∑(゚Д゚ノ)ノ

 class DynamicProxyClient {

     public static void main(String[] args) {
DynamicProxyDemo dynamic = new DynamicProxyDemo(new Celebrity());
Agent agent = (Agent) dynamic.getProxy();
agent.advertising();
agent.collectMoney();
agent.travelArrangements();
}
}

SpringCloud学习笔记(一、SpringCloud 基础)的更多相关文章

  1. SpringCloud学习笔记:SpringCloud简介(1)

    1. 微服务 微服务具有的特点: ◊ 按照业务划分服务 ◊ 每个微服务都有独立的基础组件,如:数据库.缓存等,且运行在独立的进程中: ◊ 微服务之间的通讯通过HTTP协议或者消息组件,具有容错能力: ...

  2. SpringCloud学习笔记(2):使用Ribbon负载均衡

    简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡工具,在注册中心对Ribbon客户端进行注册后,Ribbon可以基于某种负载均衡算法,如轮询(默认 ...

  3. SpringCloud学习笔记(3):使用Feign实现声明式服务调用

    简介 Feign是一个声明式的Web Service客户端,它简化了Web服务客户端的编写操作,相对于Ribbon+RestTemplate的方式,开发者只需通过简单的接口和注解来调用HTTP API ...

  4. SpringCloud学习笔记(4):Hystrix容错机制

    简介 在微服务架构中,微服务之间的依赖关系错综复杂,难免的某些服务会出现故障,导致服务调用方出现远程调度的线程阻塞.在高负载的场景下,如果不做任何处理,可能会引起级联故障,导致服务调用方的资源耗尽甚至 ...

  5. SpringCloud学习笔记(5):Hystrix Dashboard可视化监控数据

    简介 上篇文章中讲了使用Hystrix实现容错,除此之外,Hystrix还提供了近乎实时的监控.本文将介绍如何进行服务监控以及使用Hystrix Dashboard来让监控数据图形化. 项目介绍 sc ...

  6. SpringCloud学习笔记(6):使用Zuul构建服务网关

    简介 Zuul是Netflix提供的一个开源的API网关服务器,SpringCloud对Zuul进行了整合和增强.服务网关Zuul聚合了所有微服务接口,并统一对外暴露,外部客户端只需与服务网关交互即可 ...

  7. SpringCloud学习笔记(7):使用Spring Cloud Config配置中心

    简介 Spring Cloud Config为分布式系统中的外部化配置提供了服务器端和客户端支持,服务器端统一管理所有配置文件,客户端在启动时从服务端获取配置信息.服务器端有多种配置方式,如将配置文件 ...

  8. SpringCloud学习笔记:服务支撑组件

    SpringCloud学习笔记:服务支撑组件 服务支撑组件 在微服务的演进过程中,为了最大化利用微服务的优势,保障系统的高可用性,需要通过一些服务支撑组件来协助服务间有效的协作.各个服务支撑组件的原理 ...

  9. js学习笔记:webpack基础入门(一)

    之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...

  10. Java学习笔记:语言基础

    Java学习笔记:语言基础 2014-1-31   最近开始学习Java,目的倒不在于想深入的掌握Java开发,而是想了解Java的基本语法,可以阅读Java源代码,从而拓展一些知识面.同时为学习An ...

随机推荐

  1. FAQ – Automatic Undo Management (AUM) / System Managed Undo (SMU) (Doc ID 461480.1)

    FAQ – Automatic Undo Management (AUM) / System Managed Undo (SMU) (Doc ID 461480.1) APPLIES TO: Orac ...

  2. dd 工具使用; SSD 顺序写性能测试;

    dd 工具使用: dd 也是我们经常使用到的磁盘测试工具,Linux服务器装好系统之后,想要知道硬盘的读写是否能满足服务的需要,如果不满足硬盘的IO就是服务的一个瓶颈.我们可以使用dd命令简单进行测试 ...

  3. Python—图形界面开发

    https://blog.csdn.net/kun_dl/category_7418837.html https://www.runoob.com/python/python-gui-tkinter. ...

  4. 002.SQLServer数据库镜像高可用简介

    一 数据库镜像简介 1.1 数据库镜像概述 数据库镜像维护一个数据库的两个副本,这两个副本必须驻留在不同的 SQL Server 数据库引擎服务器实例上. 通常,这些服务器实例驻留在不同位置的计算机上 ...

  5. Centos 静态网络配置

    cat /etc/sysconfig/network-scripts/ifcfg-ens33 DEFROUTE="yes" IPV4_FAILURE_FATAL="no& ...

  6. vue模板语法下

    样式绑定 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <titl ...

  7. list集合优化,泛型的使用以及坼箱和装箱

    1.list vector线程同步,线程安全arraylist的运行速度较快,因为没有使用线程 LlinkedList以链表结构存储数据 2.泛型泛型类 泛型接口 泛型方法 泛型的属性泛型的属性 属性 ...

  8. Comet OJ - Contest #8

    Comet OJ - Contest #8 传送门 A.杀手皇后 签到. Code #include <bits/stdc++.h> using namespace std; typede ...

  9. (day59)十一、CSRF、Auth模块、impotlib模块、settings源码

    目录 一.模拟实现中间件的编程思想 (一)impotlib模块 (二)实现功能的配置使用 二.跨站请求伪造CSRF (一)由来 (二)form表单的CSRF (三)ajax中的CSRF (1)通过da ...

  10. CSP-S 2019文澜中学游记(11.15~11.17)

    前言 今年的\(CSP-S\),本以为自己的实力与去年的\(NOIP\)相比,能有较大的提升的. 没想到,菜是原罪,弱就是弱,依然逃脱不了被吊锤的命运. \(Nov\ 15th\):\(Day\ 0\ ...