Spring、SpringBoot、SpringCloud

1.讲讲Spring的IOC和AOP的理解

  • AOP

    • 面向切面编程 横切面影响多个方法 每个方法如同一个点,多个方法形成面

      • 增强 @Aspect

      • 前置 后置 环绕

      • cglib && jdk动态代理

      • 简化版:
          - JDK动态代理是面向接口的。
          - CGLib动态代理是利用ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理,因此如果被代理类被final关键字所修饰,会失败。
          
          
        使用注意:
        ​
        如果要被代理的对象是个实现类,那么Spring会使用JDK动态代理来完成操作(Spirng默认采用JDK动态代理实现机制);
        ​
        如果要被代理的对象不是个实现类那么,Spring会强制使用CGLib来实现动态代理。
        ​
        ​
        补充(了解即可):
        ASM 是一个 Java 字节码操控框架。
        它能被用来动态生成类或者增强既有类的功能。
        ​
        JDK动态代理详细步骤(了解即可):
          - 通过实现InvocationHandler接口创建自己的调用处理器;
          - 通过为Proxy类指定ClassLoader对象和一组interface来创建动态代理;
          - 通过反射机制获取动态代理类的构造函数,其唯一参数类型就是调用处理器接口类型;
          - 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数参入;
          熟悉:
          - JDK动态代理是面向接口的代理模式,如果被代理目标没有接口那么Spring也无能为力,Spring    通过Java的反射机制生产被代理接口的新的匿名实现类,重写了其中AOP的增强方法。
        ​
    • 使用场景

      • 统一日志

      • 统一异常

      • 有个需求:针对某些接口里面的方法,判断这些方法入参中的skuId是否为空,为空,返回统一异常,不为空,正常执行业务逻辑

      • getArgs获取入参

      • 正常执行 .proceed();

    •  

  • IOC 控制反转思想

    • 本来是我们自己手动new出来的对象,现在则把对象交给Spring的IOC容器管理

    • IOC容器可以理解为一个对象工厂,我们都把该对象交给工厂,工厂管理这些对象的创建以及依赖关系

    • DI:依赖注入,把对应的属性的值注入到具体的对象当中。

      • 构造器注入,spring官方推荐

      • setter方法注入,这种方式在开发中相对不常见

      • 通过Field属性注入,比如@Autowired,@Resource

    • 容器:存储对象,使用map结构来进行存储,在spring中一般存在三级缓存,singletonObjects(一级缓存)存放完整的bean对象,整个bean的生命周期,从创建到使用到销毁的整个过程都是由容器来管理的。

    • 在我们聊ioc容器的时候要涉及容器的创建过程

      • BeanFactory, DefaultListableBeanFactory 创建bean工厂

      • 向bean工厂中设置一些参数等属性

      • 加载解析bean对象,准备要创建的bean对象 的 定义对象beanDefinition(xml配置文件spring.factories/注解的解析过程)

        • BeanFactoryPostProcessor 的处理,此处是扩展点

          • PlaceHolderConfigurerSupport 处理占位符 是BeanFactory的后置处理器

          • ConfigurationClassPostProcessor 是BeanFactory的后置处理器

            • 扫描程序员配置,把需要转化的类全部转为BeanDefinition

              • @Configuration

              • @ComponentScan、@ComponentScans

      • BeanPostProcessor的注册,方便后续对bean对象完成具体的扩展功能

      • 通过反射的方式将BeanDefinition对象实例化成具体的bean对象

      • bean对象的初始化过程(生命周期)

        • 填充属性

        • 调用aware子类方法

        • 调用BeanPostProcessor前置处理方法

        • 调用init-method方法

        • 调用BeanPostProcessor后置处理方法

      • 生成完整的bean对象(初始化完成的对象),通过getBean方法可以直接获取

      • 销毁过程

      • 上述流程困难的话,可以简单说一下没怎么仔细研究源码,具体细节记不太清楚了,但是spring中的bean都是通过反射的方式生成的,同时其中包含了很多的扩展点,比如最常用的对BeanFactory的扩展,对bean的扩展(@Value(${xxx})),我们简单使用过一些,除此之外,ioc中最核心的就是填充具体bean的属性和生命周期。

2.ApplicationContext有了解吗?(了解即可)

  • ApplicationContext 与 BeanFactory 有什么区别?

  • 提供创建bean,获取bean,还支持国际化,事件广播,获取资源等

  • EnvironmentCapable

    • 继承此接口,表示拥有了获取环境变量的功能,可以使用ApplicationContext来获取操作系统中的环境变量和JVM环境变量

  • ListableBeanFactory

    • 拥有获取所有beanNames,判断某个beanName是否存在beanDefinition对象,统计BeanDefinition个数,获取某个类型对应的所有beanNames等功能

  • HierarchicalBeanFactory

    • 可以获取父BeanFactory,判断某个name是否存在bean对象的功能

  • MessageSource

    • 国际化功能,可以获取某个国际化资源(比如不同国家语言对应的字符)

  • ApplicationEventPublisher

    • 事件发布功能

  • ResourcePatternResolver

    • 加载并获取资源的功能,资源可以是文件,图片等某个URL资源

3.bean生命周期有了解过吗?

  • 实例化 和 初始化 ?new A();

 

  • beanDefinition --> 实例化 --> 初始化 --> 使用/销毁

  • 实例化bean:反射方式生成对象(根据beanDefinition反射生成)

  • 填充bean属性:调用populateBean();

  • 调用Aware相关接口:invokeAwareMethod完成beanName,BeanFactory,BeanClassLoader对象的属性设置

  • 调用BeanPostProcessor中的前置处理方法:ApplicationContextPostProcessor,来填充ApplicationContext等相关对象

  • 调用init-method方法: invokeInitMethod(),判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有则不调用

  • 调用BeanPostProcessor中的后置方法:spring的aop就是在此处实现的,AbstractAutoProxyCreator

  • 注册Destuction相关的回调接口

  • 获取完整对象,通过getBean的方式来进行获取对象

  • 销毁过程

    • 判断是否实现了DisposableBean接口

    • 调用destoryMethod方法

4.Spring是如何解决循环依赖问题的?三级缓存有了解吗?为什么有三级缓存?

  • 解释循环依赖 A依赖B B依赖A

    • 先创建A对象,实例化A对象,此时A对象中的b属性为空,填充属性b

    • 从容器中查找B对象,如果找到了,直接赋值,此时不存在循环依赖问题,找不到直接创建B对象

    • 实例化B对象,此时B对象中的a属性为空,填充属性a

    • 从容器中查找A对象,找不到,直接创建

    • 上面是形成闭环的原因

      • 此时你会发现A对象是存在的,只不过此时A对象不是一个完整的状态,只是完成了实例化但是未完成初始化

      • 如果程序在调用过程中,拥有了某个对象的引用,可以把非完整状态的对象先赋值,相当于提前暴露了某个不完整对象的引用

      • 所以解决问题的核心在于,实例化和初始化分开操作,这也是解决循环依赖问题的关键,当所有的对象都完成实例化和初始化操作之后,还要把完整对象放到容器中,此时在容器中存在对象的几个状态?

        • 完成实例化但未完成初始化

        • 完成状态(完成初始化)

        • 由于存在上述两种状态的对象在容器中,所以需要使用不同的map结构来存储,此时就有了一级缓存和二级缓存在进行存储,如果一级缓存中存在,那么二级缓存中就不会存在同名的对象,因为缓存的查找顺序是按照1->2->3级缓存进行查找的

          • 一级缓存中放的是完整的对象

          • 二级缓存中放的是非完整对象

          • 三级缓存是干嘛的?

            • 解决AOP动态代理

            • 早期的bean都是放在三级缓存中的,在后续的使用过程中, 如果需要被代理则返回代理对象,给到二级缓存中,后续对象初始化完成后再同步到一级缓存进行使用

               

5.BeanFactory和FactoryBean有什么区别?

  • 都是用来创建bean的

  • 使用BeanFactory创建对象的时候,必须要遵守严格的生命周期流程

  • 如果要简单自定义某个对象的创建,同时创建的对象要交给spring进行管理,那么就要实现FactoryBean接口了

    • isSingleton:是否是单例对象

    • getObjectType:获取返回对象的类型

    • getObject:自定义创建对象的过程(new,反射,动态代理)

6.Spring中用到哪些设计模式?

  • 单例模式:bean默认都是单例模式

  • 工厂模式:BeanFactory ApplicationContext 创建bean对象

  • 策略模式:XmlBeanDefinitionReader

  • 代理模式:aop动态代理

    • 事务注解

  • 。。。。。

7.说一说Spring的事务传播行为(机制)?(熟记)

  • 保证同一个事务中:
    ​
    PROPAGATION_REQUIRED 如果当前没有事务,则自己新建一个事务,如果当前存在事务,则加入这个事务
    ​
    PROPAGATION_SUPPORTS 当前存在事务,则加入当前事务,如果当前没有事务,就以非事务方法执行
    ​
    PROPAGATION_MANDATORY 当前存在事务,则加入当前事务,如果当前事务不存在,则抛出异常
    ​
    保证没有在同一个事务中:
    ​
    PROPAGATION_REQUIRES_NEW 创建一个新事务,如果存在当前事务,则挂起该事务
    ​
    PROPAGATION_NOT_SUPPORTED 始终以非事务方式执行,如果当前存在事务,则挂起当前事务
    ​
    PROPAGATION_NEVER 不使用事务,如果当前事务存在,则抛出异常
    ​
    PROPAGATION_NESTED 如果当前事务存在,则在嵌套事务中执行,否则REQUIRED的操作一样(开启一个事务)

8.讲一讲Spring事务隔离级别?(熟记)

  • 不做隔离级别会发生什么?
    ​
    事务的特性是ACID
    ​
    原子性 (atomicity):强调事务的不可分割.
    ​
    一致性 (consistency):事务的执行的前后数据的完整性保持一致.
    ​
    隔离性 (isolation):一个事务执行的过程中,不应该受到其他事务的干扰
    ​
    持久性(durability) :事务一旦结束,数据就持久到数据库
    ​
    如果不考虑隔离性引发安全性问题:
    ​
    脏读 :一个事务读到了另一个事务的未提交的数据
    ​
    不可重复读 :一个事务读到了另一个事务已经提交的 update 的数据导致多次查询结果不一致.
    ​
    虚/幻读 :一个事务读到了另一个事务已经提交的 insert/delete 的数据导致多次查询结果不一致.
    ​
    ​
    解决方案:
    ​
    DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.
    ​
    未提交读(read uncommited) :脏读,不可重复读,虚读都有可能发生
    read uncommited:是最低的事务隔离级别,它允许另外一个事务可以看到这个事务未提交的数据。
    ​
    已提交读 (read commited):避免脏读。但是不可重复读和虚读有可能发生
    read commited:保证一个事物提交后才能被另外一个事务读取。另外一个事务不能读取该事物未提交的数据。
    ​
    可重复读 (默认数据库隔离级别 repeatable read) :避免脏读和不可重复读,但是虚读有可能发生。(innodb mvcc机制gap lock保证不存在幻读)
    repeatable read:这种事务隔离级别可以防止脏读,不可重复读。但是可能会出现幻象读。它除了保证一个事务不能被另外一个事务读取未提交的数据之外还避免了以下情况产生(不可重复读)。
    ​
    串行化的 (serializable) :避免以上所有读问题.
    serializable:这是花费最高代价但最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读之外,还避免了幻象读(避免三种)。

9.Spring中的bean线程一定是安全的吗?

  • 只有有状态的单例bean才会有线程安全问题

    • 问题涉及要bean的scope以及bean的状态

  • bean的作用域

    • prototype 多例bean。每次getBean()的时候,都会创建一个新的对象

    • singleton 单例bean。在Spring容器中只会存在一个全局共享的实例

      • 无状态bean

        • 多线程操作中,只会对成员变量进行查询操作,不会修改成员变量的值

      • 有状态bean

        • 多线程操作中,对成员变量进行更新操作,修改成员变量的值

    • 解决方案

      • 将singleton改为prototype

      • 避免在bean中定义可变的成员变量

      • 可变成员变量保存在ThreadLocal中,ThreadLocal具备线程隔离的特性,每个线程取操作自己的变量副本即可

10.spring mvc的DispatchServerlet执行流程?(熟记)

 

  • 客户端(浏览器)发送请求,直接请求到 DispatcherServlet。

  • DispatcherServlet 根据请求信息调用 HandlerMapping,解析请求对应的 Handler。

  • 解析到对应的 Handler(也就是我们平常说的 Controller 控制器)后,开始由 HandlerAdapter 适配器处理。

  • HandlerAdapter 会根据 Handler 来调用真正的处理器来处理请求,并处理相应的业务逻辑。

  • 处理器处理完业务后,会返回一个 ModelAndView 对象,Model 是返回的数据对象,View 是个逻辑上的 View。

  • ViewResolver 会根据逻辑 View 查找实际的 View。

  • DispaterServlet 把返回的 Model 传给 View(视图渲染)。

  • 把 View 返回给请求者(浏览器)

  • 将一个类声明为Spring的 bean 的注解有哪些?

    • 我们一般使用 @Autowired 注解自动装配 bean,要想把类标识成可用于 @Autowired 注解自动装配的 bean 的类,采用以下注解可实现:

    • @Component :通用的注解,可标注任意类为 Spring 组件。如果一个Bean不知道属于哪个层,可以使用@Component 注解标注

    • @Repository/@Mapper : 对应持久层即 Dao 层,主要用于数据库相关操作

    • @Service : 对应服务层,主要涉及一些核心业务的处理逻辑,需要用到 Dao层

    • @Controller : 对应 Spring MVC 控制层,主要用户接受用户请求并调用 Service 层返回数据给前端页面

SpringBoot

1.SpringBoot有哪些优点?(了解即可)

  • 独立运行

    • Spring Boot而且内嵌了各种servlet容器,Tomcat、Jetty等,现在不再需要打成war包部署到容器中,Spring Boot只要打成一个可执行的jar包就能独立运行,所有的依赖包都在一个jar包内

  • 简化配置

    • spring-boot-starter-web启动器自动依赖其他组件,减少了maven的配置。除此之外,还提供了各种启动器,开发者能快速上手

  • 自动配置

    • Spring Boot能根据当前类路径下的类、jar包来自动配置bean,如添加一个spring-boot-starter-web启动器就能拥有web的功能,无需其他配置。

  • 无代码生成和XML配置

    • Spring Boot配置过程中无代码生成,也无需XML配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的,这也是Spring4.x的核心功能之一

  • 应用监控

    • Spring Boot提供一系列端点可以监控服务及应用,做健康检测

2.核心注解有哪些?都由哪些注解构成?

  • 启动类上面的@SpringBootApplication,主要组合包含了以3 个注解

    • @SpringBootConfiguration:组合了 @Configuration 注解,实现配置文件的功能

    • @EnableAutoConfiguration:打开自动配置的功能,也可以关闭某个自动配置的选项

    • @ComponentScan:Spring组件扫描

3.自动装配简单说一下(最高频)

  • 自动将第三方的组件装载到IOC容器当中,无需再去关心相关bean的配置

    • 在启动类上添加@SpringBootApplication实现自动装配

      • @EnableAutoConfiguration

    • 引入starter组件,组件中必须包含@Configuration,通过@Bean注解声明需要装配到IOC容器的对象

    • 约定大于配置,(classpath:/META-INF/spring.factories)将第三方jar包配置类全路径路径进行扫描加载

    • 通过spring的ImportSelector接口实现对配置类的动态加载,从而完成自动装配

SpringCloud

1.请简单描述一下SpringCloud(了解)

  • Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、智能路由、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。

  • Spring Cloud并没有重复制造轮子,它只是将各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。

2.有什么优势?(了解)

  • 耦合度比较低,不会影响其他模块的开发。

  • 减轻团队的成本,可以并行开发,不用关注其他人怎么开发,先关注自己的开发。

  • 配置比较简单,基本用注解就能实现,不用使用过多的配置文件。

  • 微服务跨平台的,可以用任何一种语言开发。

  • 每个微服务可以有自己的独立的数据库也有用公共的数据库。

  • 直接写后端的代码,不用关注前端怎么开发,直接写自己的后端代码即可,然后暴露接口,通过组件进行服务通信。

3.有什么缺点呢?(了解)

  • 部署比较麻烦,给运维工程师带来一定的麻烦。

  • 针对数据的管理比麻烦,因为微服务可以每个微服务使用一个数据库。

  • 系统集成测试比较麻烦

  • 性能的监控比较麻烦。【最好开发一个大屏监控系统】

4.SpringCloud Alibaba中有哪些组件?

  • Sentinel:由阿里巴巴开源,把流量作为切入点,从流量控制、熔断和降级、系统负载保护等多个维度保护服务的稳定性。

    • 谈谈你对服务降级,和服务熔断的理解

      • 当客户端请求服务器的时候,防止客户端一直等待,不会处理业务逻辑代码,直接返回给客户端一个友好的提示

      • 服务熔断是在服务降级之上更直接的一种保护方式,当在某个时间段内的请求失败量达到设定的阈值,或者是当前的请求错误率达到设定的阈值,开启熔断,之后的请求直接走fallback方法,在一定(设置)时间后尝试恢复

    • Sentinel 和 Hystrix 有什么区别?

      • Hystrix主要以隔离和熔断为容错机制,超时或被熔断的请求将快速失败,能够fallback以及降级

        • 服务隔离是Hystrix为隔离的服务开启一个独立的线程池,保证在高并发的场景下不会影响其他服务。

      • Sentinel则主要在多样化的流量控制、熔断降级、系统负载保护等。

  • Nacos:由阿里巴巴开源,是一个更易于构建云原生应用的服务发现、配置管理和服务管理平台

    • nacos相较于Eureka的区别和优势是什么?

      • 区别

        • Eureka采用ap模式形式实现注册中心

        • Nacos默认采用AP模式,在1.0版本之后采用ap+cp模式混合实现注册中心

      • 优势

        • nacos在自动或手动下线服务,使用消息机制通知客户端,服务实例的修改很快响应;Eureka只能通过任务定时剔除无效的服务。

        • nacos可以根据namespace命名空间,DataId,Group分组,来区分不同环境(dev,test,pre,prod),不同项目的配置。

  • RocketMQ:基于Java的高性能、高吞吐量的分布式消息和流计算平台。

  • Dubbo:一款高性能Java RPC 通信服务框架。

    • 简单说一下dubbo和feign各自的优势吧

      • dubbo除了注册中心需要整合,负载均衡,服务治理,容错机制等都自己实现了,而feign需要依托于cloud的全家桶来实现

      • 如果项目对于性能要求的不是很严格,可以使用feign,使用起来也更加方便,如果对性能有更高的要求,规避http的性能瓶颈,可以选择使用dubbo

  • Seata:由阿里巴巴开源,是一个易于使用的高性能的微服务分布式事务解决方案。

  • Alibaba Cloud OSS:阿里云对象存储服务,是阿里云提供的海量、安全、低成本、高可靠的云存储服务。

  • Alibaba Cloud SchedulerX:阿里巴巴中间件团队开发的一款分布式任务调度产品,支持周期性触发任务与固定时间点触发任务。

  • Alibaba Cloud SMS:覆盖全球的短信服务,拥有友好、高效、智能的互联通信能力,可帮助企业迅速搭建客户触达通道。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【2021年,将Spring全家桶的课程进行Review,确保不再有课程的顺序错乱,从而导致学员看不懂。进入2022年,将Spring的课程进行整理,整理为案例精讲的系列课程,并开始加入高阶Spring Security等内容,一步步手把手教你从零开始学会应用Spring,课件将逐步进行上传,敬请期待!】 本课程是Spring全家桶系列课程的第三部分Spring BootSpring案例精讲课程以真实场景、项目实战为导向,循序渐进,深入浅出的讲解Java网络编程,助力您在技术工作中更进一步。 本课程聚焦Spring Boot核心知识点:整合Web(如:JSP、Thymeleaf、freemarker等的整合)的开发、全局异常处理、配置文件的配置访问、多环境的配置文件设置、日志Logback及slf4j的使用、国际化设置及使用, 并在最后以一个贯穿前后台的Spring Boot整合Mybatis的案例为终奖,使大家快速掌握Spring的核心知识,快速上手,为面试、工作都做好充足的准备。 由于本课程聚焦于案例,即直接上手操作,对于Spring的原理等不会做过多介绍,希望了解原理等内容的需要通过其他视频或者书籍去了解,建议按照该案例课程一步步做下来,之后再去进一步回顾原理,这样能够促进大家对原理有更好的理解。 【通过Spring全家桶,我们保证你能收获到以下几点】 1、掌握Spring全家桶主要部分的开发、实现2、可以使用Spring MVC、Spring BootSpring CloudSpring Data进行大部分的Spring开发3、初步了解使用微服务、了解使用Spring进行微服务的设计实现4、奠定扎实的Spring技术,具备了一定的独立开发的能力  【实力讲师】 毕业于清华大学软件学院软件工程专业,曾在Accenture、IBM等知名外企任管理及架构职位,近15年的JavaEE经验,近8年的Spring经验,一直致力于架构、设计、开发及管理工作,在电商、零售、制造业等有丰富的项目实施经验  【本课程适用人群】如果你是一定不要错过!  适合于有JavaEE基础的,如:JSP、JSTL、Java基础等的学习者没有基础的学习者跟着课程可以学习,但是需要补充相关基础知识后,才能很好的参与到相关的工作中。 【Spring全家桶课程共包含如下几门】 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值