Java面试题总结 | Java面试题总结10- Feign和设计模式模块(持续更新)

Feign

项目中如何进行通信

在调用模块的启动类上添加 @EnableFeignCleints 注解,以及@EnableDiscoveryClient

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jYU2Tmn4-1683165926603)(D:/学习/JAVA/面经/面试题整理版本.assets/image-20220909084447460.png)]

然后再配置文件中,将他的服务注册到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)也称发布订阅模式,它的目的是定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

连接数据库使用的是-单例模式

权限管理-代理模式

代理模式是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。

写单例的时候需要注意什么

  1. 单例模式保证了系统内存中该例只存在一个对象,节省了系统资源,使用单例模式可以提高系统性能
  2. 当要实例化一个单例对象的时候,要使用相应的获取对象的方法而不是new
  3. 单例模式使用的场景:需要频繁的进行创建和销毁的对象、创建对象时耗时过多或耗费资源过多(即:重量级对象),但又经常用到的对象、工具类对象、频繁访问数据库或文件的对象(比如数据源、session工厂等)

工厂模式的理解

工厂模式顾名思义就是用来生产对象的,在java中,万物皆对象,有很多多想需要创建如果创建一个对象就new该对象,会对该对象耦合严重,如果需要更换该对象,就要把用到该对象的地方全都更改

如果使用工厂模式,在更换对象的时候只需要在生产对象的工厂中做更改就可以了,降低了对象耦合性。

工厂模式分为三种模式:

(1)简单工厂模式,一个工厂方法,**根据传入的参数返回要生成的对象,这种模式将创建对象从应用代码中抽离,但是不能动态的改变创建行为,**比如工厂可以生成苹果对象和橘子对象,但是后来又需要生产桃子对象,就必须修改工厂类,局限性很大。

(2)**工厂方法模式,将工厂提取为抽象类或接口,具体生产什么对象由子类决定,比如生产苹果和生产橘子的工厂类继承水果工厂抽象类,子类各自生产各自对象,需要生产什么水果就调用哪个工厂类。**这种模式与简单工厂模式一个意思,需要生产桃子对象时必须要再创建出一个桃子工厂继承水果工厂,还是局限性很大。

(3)抽象工厂模式,当需要生产的对象比较多而且有依赖关系时可以使用抽象工厂模式。比如,现在需要生产苹果汁,苹果派,香蕉汁,香蕉派4个对象,可以分为香蕉和苹果两类,先创建一个抽象类生产果汁和派,然后苹果工厂来继承这个抽象类,重写生产果汁和派的两个方法生产苹果汁和苹果派,同理香蕉工厂也继承它生产香蕉汁和香蕉派,降低了对象的耦合性

设计模式了解么

工厂设计模式

定义一个用于创建对象的接口,让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。(即当在客户端怎加产品时,只需增加具体产品类和具体工厂类就可以

Spring使用工厂模式可以通过 BeanFactoryApplicationContext 创建 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 中 jdbcTemplatehibernateTemplate 等以 Template 结尾的对数据库操作的类,它们就使用到了模板模式。

观察者模式

观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。

适配器模式

观察者模式

观察者模式是一种对象行为型模式。它表示的是一种对象与对象之间具有依赖关系,当一个对象发生改变的时候,这个对象所依赖的对象也会做出反应。Spring 事件驱动模型就是观察者模式很经典的一个应用。Spring 事件驱动模型非常有用,在很多场景都可以解耦我们的代码。比如我们每次添加商品的时候都需要重新更新商品索引,这个时候就可以利用观察者模式来解决这个问题。

适配器模式

pring AOP 的增强或通知(Advice)使用到了适配器模式

猜你喜欢

转载自blog.csdn.net/qq_43167873/article/details/130481531