文章目录
- Feign
- 项目中如何进行通信
- Feign原理简述
- 设计模式
- spring用到的设计模式
- 项目的场景中运用了哪些设计模式
- 写单例的时候需要注意什么
- 工厂模式的理解
- 设计模式了解么
- 工厂设计模式
- 单例设计模式
- 代理设计模式
- 策略模式
- **模板方法模式**
- 观察者模式
- **适配器模式**
- 观察者模式
- **适配器模式**
Feign
项目中如何进行通信
在调用模块的启动类上添加 @EnableFeignCleints 注解,以及@EnableDiscoveryClient
然后再配置文件中,将他的服务注册到nacos中;
把所有被调用的类集成下一个模块中,接下来创建一个被调用的类,在这个类上添加注解@FeignClient(value = “service-cmn”),在value中写入被调用的服务名称,将调用的方法复制过来,写成接口的形式,然后在Maping注解中,将完整的接口地址写入;接下来在调用的模块将被调用的模块注入进入;
继续深入看一下注解内部都做了什么。注解内部的方法就不说明了,不加会有默认的配置
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {...}
前三个注解看着平平无奇,重点在第四个 @Import 上,一般使用此注解都是想要动态注册 Spring Bean 的
花一个周末,掌握 SpringCloud OpenFeign 核心原理 - 知乎 (zhihu.com)
Feign原理简述
- 通过 @EnableFeignCleints 注解启动 Feign Starter 组件
- Feign Starter 在项目启动过程中注册全局配置,扫描包下所有的 @FeignClient 接口类,并进行注册 IOC 容器
- @FeignClient 接口类被注入时,通过
FactoryBean#getObject
返回动态代理类 - 接口被调用时被动态代理类逻辑拦截,将 @FeignClient 请求信息通过编码器生成 Request
- 交由 Ribbon 进行负载均衡,挑选出一个健康的 Server 实例
- 继而通过 Client 携带 Request 调用远端服务返回请求响应
- 通过解码器生成 Response 返回客户端,将信息流解析成为接口返回数据
主程序入口添加了@EnableFeignClients注解开启对FeignClient扫描加载处理。根据Feign Client的开发规范,定义接口并加@FeignClientd注解。
当程序启动时,会进行包扫描,扫描所有@FeignClients的注解的类,并且将这些信息注入Spring IOC容器中,当定义的的Feign接口中的方法被调用时,通过JDK的代理方式,来生成具体的RequestTemplate.
当生成代理时,Feign会为每个接口方法创建一个RequestTemplate。当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,该对象封装了HTTP请求需要的全部信息,如请求参数名,请求方法等信息都是在这个过程中确定的。
然后RequestTemplate生成Request,然后把Request交给Client去处理,这里指的是Client可以是JDK原生的URLConnection,Apache的HttpClient,也可以是OKhttp,最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发起服务之间的调用。
总结:
在调用的微服务模块上加上@EnableFeignClients,启动微服务时,通过@EnableFeignClients注解去启动Feign stater 扫描所有的@FeignClient注解类,将这些类注册到IOC容器中,通过JDK动态代理的方式,来生成具体RequestTemplate对象,该对象封装了@FeignClient请求的全部信息,RequestTemplate对象生成request交给Rabbion进行负载均衡,Rabbin挑选出一个健康的server实例,去完成请求返回响应;
设计模式
spring用到的设计模式
- 工厂模式:BeanFactory /ApplicationContext就是简单工厂模式的体现,用来创建对象的实例;
- 单例模式:Bean 默认为单例模式。
- 代理模式:能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
- 模板方法:用来解决代码重复的问题。比如. RestTemplate,jdbcTemplate, JpaTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式
项目的场景中运用了哪些设计模式
登陆功能-用到了策略模式
策略模式(Strategy Pattern)也叫政策模式,是一种比较简单的模式。它的目的是定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换,使得算法可以在不影响到客户端的情况下发生变化。
用户下单-用到了观察者模式
观察者模式(Observer Pattern)也称发布订阅模式,它的目的是定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
连接数据库使用的是-单例模式
权限管理-代理模式
代理模式是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。
写单例的时候需要注意什么
- 单例模式保证了系统内存中该例只存在一个对象,节省了系统资源,使用单例模式可以提高系统性能
- 当要实例化一个单例对象的时候,要使用相应的获取对象的方法而不是new
- 单例模式使用的场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)
工厂模式的理解
工厂模式顾名思义就是用来生产对象的,在java中,万物皆对象,有很多多想需要创建如果创建一个对象就new该对象,会对该对象耦合严重,如果需要更换该对象,就要把用到该对象的地方全都更改
如果使用工厂模式,在更换对象的时候只需要在生产对象的工厂中做更改就可以了,降低了对象耦合性。
工厂模式分为三种模式:
(1)简单工厂模式,一个工厂方法,**根据传入的参数返回要生成的对象,这种模式将创建对象从应用代码中抽离,但是不能动态的改变创建行为,**比如工厂可以生成苹果对象和橘子对象,但是后来又需要生产桃子对象,就必须修改工厂类,局限性很大。
(2)**工厂方法模式,将工厂提取为抽象类或接口,具体生产什么对象由子类决定,比如生产苹果和生产橘子的工厂类继承水果工厂抽象类,子类各自生产各自对象,需要生产什么水果就调用哪个工厂类。**这种模式与简单工厂模式一个意思,需要生产桃子对象时必须要再创建出一个桃子工厂继承水果工厂,还是局限性很大。
(3)抽象工厂模式,当需要生产的对象比较多而且有依赖关系时可以使用抽象工厂模式。比如,现在需要生产苹果汁,苹果派,香蕉汁,香蕉派4个对象,可以分为香蕉和苹果两类,先创建一个抽象类生产果汁和派,然后苹果工厂来继承这个抽象类,重写生产果汁和派的两个方法生产苹果汁和苹果派,同理香蕉工厂也继承它生产香蕉汁和香蕉派,降低了对象的耦合性
设计模式了解么
工厂设计模式
定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。(即当在客户端怎加产品时,只需增加具体产品类和具体工厂类就可以)
Spring使用工厂模式可以通过 BeanFactory
或 ApplicationContext
创建 bean 对象。
两者对比:
BeanFactory
:延迟注入(使用到某个 bean 的时候才会注入),相比于ApplicationContext
来说会占用更少的内存,程序启动速度更快。ApplicationContext
:容器启动的时候,不管你用没用到,一次性创建所有 bean 。BeanFactory
仅提供了最基本的依赖注入支持,ApplicationContext
扩展了BeanFactory
,除了有BeanFactory
的功能还有额外更多功能,所以一般开发人员使用ApplicationContext
会更多。
单例设计模式
对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法)。
Spring 中 bean 的默认作用域就是 singleton(单例)的。
1. 构造私有:
如果要保证一个类不能多次被实例化,那么我肯定要阻止对象被new 出来,所以需要把类的所有构造方法私有化。
2.以静态方法返回实例。
因为外界就不能通过new来获得对象,所以我们要通过提供类的方法来让外界获取对象实例。
3.确保对象实例只有一个。
只对类进行一次实例化,以后都直接获取第一次实例化的对象。
饿汉模式
饿汉模式的意思是,我先把对象(面包)创建好,等我要用(吃)的直接直接来拿就行了。
懒汉模式
因为饿汉模式可能会造成资源浪费的问题,所以就有了懒汉模式,懒汉模式的意思是,我先不创建类的对象实例,等你需要的时候我再创建。
懒汉模式在并发情况下可能引起的问题
懒汉模式解决了饿汉模式可能引起的资源浪费问题,因为这种模式只有在用户要使用的时候才会实例化对象。但是这种模式在并发情况下会出现创建多个对象的情况。
因为可能出现外界多人同时访问SingleCase.getInstance()方法,这里可能会出现因为并发问题导致类被实例化多次,所以懒汉模式需要加上锁synchronized (Singleton.class) 来控制类只允许被实例化一次。
//懒汉模式,双重null检查
class Singleton{
private volatile static Singleton instance = null;
private Singleton(){}
public static Singleton getInstance() {
if(instance == null){
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
//饿汉模式
class Singleton2{
private static final Singleton2 instance = new Singleton2();
private Singleton2(){}
public static Singleton2 getInstance() {
return instance;
}
}
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
//静态内部类模式
public class Singleton {
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
private Singleton (){}
public static final Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
}
//枚举
public enum Singleton {
INSTANCE;
public void whateverMethod() {
}
}
代理设计模式
为一个对象提供一个替身,以控制对这个对象的访问。即通过代理对象访问目标对象,好处就是可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能。
AOP(Aspect-Oriented Programming:面向切面编程)能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。
策略模式
策略模式(Strategy Pattern)也叫政策模式,是一种比较简单的模式。它的目的是定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换,使得算法可以在不影响到客户端的情况下发生变化。
模板方法模式
模板方法模式 定义一个操作中的算法的骨架,而将一些步骤延迟到子类中,使得子类可以不改变一个算法的结构,就可以重定义该算法的某些特定步骤。
Spring 中 jdbcTemplate
、hibernateTemplate
等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。
观察者模式
观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
适配器模式
观察者模式
观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。
适配器模式
pring AOP 的增强或通知(Advice)使用到了适配器模式