1.Spring的两大核心是什么?
    IOC: 控制反转
    AOP:面向切面编程
    DI:依赖注入
    谈一谈你对IOC的理解?
    IOC的意思是控制反转

    1. 把创建对象的控制权转移到Spring容器中,容器根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复用。
    2. 我们需要对象的时候, 直接从Spring容器中获取即可.
    3. Spring的配置文件中配置了类的字节码位置及信息, 容器生成的时候加载配置文件识别字节码信息, 通过反射创建类的对象.

    Spring的IOC有三种注入方式 :构造器注入, setter方法注入, 注解注入。

    谈一谈你对DI的理解?
    DI的意思是依赖注入,在运行时依赖Ioc容器来动态注入对象所需要的外部资源。

    谈一谈你对AOP的理解?(必会)
    AOP面向切面编程,作为面向对象的一种补充,对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect).
    AOP使用的动态代理,就是说AOP框架不会去修改字节码,而是每次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调目标对象的方法。

    Spring AOP 中的动态代理主要有两种方式:
    (1)JDK 动态代理只提供接口代理,不支持类代理,核心 InvocationHandler 接口和 Proxy 类, InvocationHandler 通过 invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织 在一起,Proxy 利用 InvocationHandler 动态创建一个符合某一接口的的实例, 生成目标类的代理对象。cglib
    (2) 如果代理类没有实现 InvocationHandler 接口,那么 Spring AOP会选择使用 CGLIB 来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现 AOP。CGLIB 是通过继承 的方式做的动态代理,因此如果某个类被标记为 final,那么它是无法使用 CGLIB 做动态代理的。

    5.2 Spring的生命周期?(高薪常问)
    Spring默认对bean采用的是单例设计模式,bean创建完毕的时候会调用init-method指定的方法,然后bean对象会进入到spring的容器中,如果bean配置有id或者是name那么该bean存储到spring容器的时候会使用id或者name作为对象标记。当spring容器销毁之前会调用destroy-method指定的方法。

    5.3 Spring支持bean的作用域有几种? 每种作用域是什么样的?(必会)
    Spring支持如下5种作用域:
    (1)singleton:默认作用域,单例bean,每个容器中只有一个bean的实例。
    (2)prototype:为每一个bean请求创建一个实例。
    (3)request:为每一个request请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
    (4)session:与request范围类似,同一个session会话共享一个实例,不同会话使用不同的实例。
    (5)global-session:全局作用域,所有会话共享一个实例。

    5.4 BeanFactory和ApplicationContext有什么区别(了解)
    BeanFactory:
    Spring最顶层的接口,实现了Spring容器的最基础的一些功能, 一般面向Spring自身使用
    BeanFactory在启动的时候不会去实例化Bean,从容器中拿Bean的时候才会去实例化
    ApplicationContext:
    是BeanFactory的子接口,扩展了其功能, 一般面向程序员使用,ApplicationContext在启动的时候就把所有的Bean全部实例化了

    5.5 Spring的对象默认是单例的还是多例的? 单例bean存不存在线程安全问题呢?

    1. 在spring中的对象默认是单例的,但是也可以配置为多例。
      2. 单例bean对象存在线程安全问题。
      解决办法:在bean对象中避免定义可变成员变量; 在bean对象中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中。

    1.@Resource和@Autowired依赖注入的区别是什么? @Qualifier使用场景是什么?(了解)
    @Resource默认按byName自动注入。
    既不指定name,也不指定type,则自动按byName方式进行查找
    只指定了@Resource注解的name,则按name后的名字去bean元素里查找有与之相等的name属性的bean。
    只指定@Resource注解的type属性,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常。
    可以根据名字进行注入,如果找不到对应名字 得bean那么就会根据类型进行注入

    @Autowired默认先按byType进行匹配,如果发现找到多个bean,则又按照byName方式进行匹配,如果还有多个,则报出异常。

    @Qualifier使用场景:
    @Qualifier(“IOC容器中对象id”)可以配合@Autowird一起使用, 根据指定的id在Spring容器中匹配对象

    2.Spring框架中都用到了哪些设计模式?(必会)
    1. 工厂模式:BeanFactory就是简单工厂模式的体现,用来创建对象的实例
    2. 单例模式:Bean默认为单例模式
    3. 代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术
    4. 模板方法:用来解决代码重复的问题。比如. RestTemplate, JmsTemplate, JpaTemplate
    5. 观察者模式:一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知被自动更新,如Spring中listener的实现—ApplicationListener
    6.建造者模式(编写java代码的时候使用)更灵活的传参,创建对象

    3.Spring的常用注解(必会)
    1. @Component(任何层)
    表现层:@Controller
    业务层:@Service
    数据层:@Repository(dao): 用于实例化对象
    2. @Scope : 设置Spring对象的作用域
    @PostConstruct :用于设置Spring在创建对象之后要执行的方法
    @PreDestroy : 用于设置Spring销毁之前要执行的方法
    4. @Value: 简单属性的依赖注入
    5. @Autowired: 对象属性的依赖注入
    6. @Qualifier: 要和@Autowired联合使用,代表在按照类型匹配的基础上,再按照名称匹配。
    7. @Resource 按照属性名称依赖注入
    8. @ComponentScan: 组件扫描
    9. @Bean: 表在方法上,用于将方法的返回值对象放入容器
    10. @PropertySource: 用于引入其它的properties配置文件
    11. @Import: 在一个配置类中导入其它配置类的内容
    12. @Configuration: 被此注解标注的类,会被Spring认为是配置类。Spring在启动的时候会自动扫描并加载所有配置类,然后将配置类中bean放入Spring容器
    13. @Transactional 此注解可以标在类上,也可以表在方法上,表示当前类中的方法具有事务管理功能。
    @Aspect
    @Around 环绕注解
    @Piontcut 切入点

    1.Spring事务的实现方式和实现原理(必会)
    Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。真正的数据库层事务的提交和回滚是通过binlog或者redo log实现的。
    spring事务实现主要有两种方法
    1、编程式,beginTransaction()、commit()、rollback()等事务管理相关的方法
    2、声明式,利用注解Transactional 或者Aop配置

    2.你知道的Spring的通知类型有哪些,分别在什么时候执行?(了解)
    Spring的通知类型有五种,分别为:
    前置通知 : Before在切点运行之前执行
    后置通知 : AfterReturning 在切点正常结束之后执行
    异常通知 : AfterThrowing 在切点发生异常的时候执行
    最终通知 : After 在切点的最终执行
    环绕通知 : Around
    环绕通知运行,程序员以编码的方式自己定义通知的位置, 用于解决其他通知时序问题

    3.Spring的事务传播行为(高薪常问)
    spring事务的传播行为:当多个事务同时存在的时候,spring如何处理这些事务的行为。
    备注(方便记忆) 8个: propagation传播
    require必须的/suppor支持/mandatory 强制托管/requires-new 需要新建/ not -supported不支持/never从不/nested嵌套的
    ① PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新事务,如果当前存在事务,就加入该事务,该设置是最常用的设置。
    ② PROPAGATION_SUPPORTS:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就以非事务执行。
    ③ PROPAGATION_MANDATORY:支持当前事务,如果当前存在事务,就加入该事务,如果当前不存在事务,就抛出异常。mandatory
    ④ PROPAGATION_REQUIRES_NEW:创建新事务,无论当前存不存在事务,都创建新事务。
    ⑤ PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
    ⑥ PROPAGATION_NEVER:以非事务方式执行,如果当前存在事务,则抛出异常。
    ⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则按REQUIRED属性执行。

    4.Spring中的隔离级别 (高薪常问)
    ISOLATION隔离的意思
    ① isolationdefault:这是个 PlatfromTransactionManager 默认的隔离级别,使用数据库默认的事务隔离级别。
    ② isolation_Read uncommitted:读未提交,允许另外一个事务可以看到这个事务未提交的数据。
    ③ isolation_Read committed:读已提交,保证一个事务修改的数据提交后才能被另一事务读取,而且能看到该事务对已有记录的更新。解决脏读问题
    ④ isolation
    Repeatable read:可重复读,保证一个事务修改的数据提交后才能被另一事务读取,但是不能看到该事务对已有记录的更新。行锁repeatable read
    ⑤ isolation_serializable:一个事务在执行的过程中完全看不到其他事务对数据库所做的更新。

    1.谈一下你对SpringMVC框架的理解(了解)
    SpringMVC是一个基于Java实现了MVC设计模式的请求驱动类型的轻量级Web框架,通过把Model,View,Controller分离,将web层进行解耦,简化开发,减少出错,方便组内开发人员之间的配合。
    总的来说,SpringMVC就是将我们原来开发在servlet中的代码拆分了,一部分由SpringMVC完成,一部分由我们自己完成

    2.SpringMVC主要组件(必会)6个:
    前端控制器 DispatcherServlet:接收请求、响应结果,相当于转发器,有了DispatcherServlet 就减少了其它组件之间的耦合度。
    处理器的映射器 HandlerMapping:根据请求的URL来查找Handler
    处理器的适配器 HandlerAdapter:负责执行Handler
    处理器 Handler:处理业务逻辑的Java类
    视图解析器 ViewResolver:进行视图的解析,根据视图逻辑名将ModelAndView解析成真正的视图(view)
    视图View:View是一个接口, 它的实现类支持不同的视图类型,如jsp,freemarker,pdf等等

    3.谈一下SpringMVC的执行流程以及各个组件的作用(必会)
    image.png
    用户发送请求给前端的控制器,前端控制器接收到请求后调用处理器的映射器,处理器的映射器找到具体的处理器,生成处理器的对象及处理器的拦截器并返回给前端的控制器,前端控制器在调用控制器的适配器,控制器的适配器自己去定义一个处理器类,处理器类得到参数进行处理并返回结果给处理器的适配器,处理器的适配器将得到的结果返回给前端的控制器,前端的控制器将ModelAndView传给视图解析器,视图解析器(ViewReslover)将得到的参数从逻辑视图转换为物理视图并返回给前端控制器(DispatcherServlet),前端控制器调用物理视图进行渲染并返回。

    4.SpringMVC的常用注解(必会)7个:
    1.@RequestMapping:可以用在方法上也可以用在类上,访问的地址。
    2.@RequestBody:注解实现接收http请求的json数据,将json转换为java对象。
    3.@ResponseBody:注解实现将conreoller方法返回对象转化为json对象响应给客户。
    4.@PathVariable 用户从url路径上获取指定参数,标注在参数前 @PathVariabel(“要获取的参数名”)。
    5.@RequestParam: 标注在方法参数之前,用于对传入的参数做一些限制,支持三个属性:
    - value:默认属性,用于指定前端传入的参数名称
    - required:用于指定此参数是否必传
    - defaultValue:当参数为非必传参数且前端没有传入参数时,指定一个默认值

    1. @RestControllerAdvice 标注在一个类上,表示该类是一个全局异常处理的类。
      7. @ExceptionHandler(Exception.class) 标注在异常处理类中的方法上,表示该方法可以处理的异常类型。

    5.SpringMVC 中如何解决POST请求中文乱码问题?(了解)
    (1)解决post请求乱码问题:重写过滤器的方法,配置CharacterEncodingFilter过滤器,设置成utf-8;

    1.说一下SpringMVC支持的转发和重定向的写法(必会)
    1)转发: forward方式:在返回值前面加”forward:,比如forward:user.do?name=method4”
    2) 重定向: redirect方式:在返回值前面加redirect:, 比如redirect: http://www.baidu.com

    2.谈一下SpringMVC统一异常处理的思想和实现方式(必会)
    处理的思想:
    代码的调用者是SpringMVC框架,也就是说最终的异常会抛到框架中,由框架指定异常处理类进行统一处理

    实现方式:
    方式一: 创建一个自定义异常处理器(实现HandlerExceptionResolver接口),并实现里面的异常处理方法,再将这个 类交给Spring容器管理
    方式二: 在类上加注解(@ControllerAdvice)表明这是一个全局异常处理类,在方法上加注解(@ExceptionHandler),在 ExceptionHandler中有一个value属性,可以指定处理的异常类型

    3.在SpringMVC中, 如果想通过转发将数据传递到前台,有几种写法?(必会)
    有四种
    方式一:直接使用request域进行数据的传递
    request.setAttirbuate(“name”, value);
    方式二:使用Model进行传递,底层会将数据放入request域进行数据的传递 model.addAttribuate(“name”, value);
    方式三:使用ModelMap进行传递,底层会将数据放入request域进行数据的传递 modelmap.put(“name”,value);
    方式四:借用ModelAndView在其中设置数据和视图 (ModelAndView里面有两个域 一个是model域 一个是view域)
    mv.addObject(“name”,value); 设置数据
    mv.setView(“success”); 设置视图
    return mv;

    4.在SpringMVC中拦截器的使用步骤是什么样的?(必会)
    1. 定义一个类实现HandlerInterceptor接口并重写里面的方法
    2. 在SpringMvc的配置类上重写 addInterceptors方法, 注册拦截器并添加拦截器的对象和拦截地址。

    5.在SpringMVC中文件上传的使用步骤是什么样的? 前台三要素是什么?(必会)
    文件上传步骤:
    1.加载文件上传所需要的commons-fileupload包
    2.配置文件上传解析器,springmvc配置文件的文件上传解析器的id属性必须为multipartResolver
    3.后端接收文件的方法参数类型必须为MultipartFile,参数名称必须与前端的name属性保持一致

    文件上传前端三要素:
    1.form表单的提交方式必须为post
    2.enctype属性需要修改为:multipart/form-data
    3.必须有一个type属性为file的input标签,其中需要有一个name属性;如果需要上传多个文件需要添加 multiple属性

    SpringBoot是什么(了解)

    SpringBoot的优点(必会)

    1. 减少开发和测试时间。
    2. 使用 JavaConfig 有助于避免使用 XML文件。
    3. 避免大量的 Maven 导入和各种版本冲突。
    4. 提供意见发展方法。
    5. 通过提供默认值快速开发。
    6. 没有单独的 Web 服务器需要。不需要启动 Tomcat,Glassfish或其他任何东西。
    7. 需要更少的配置 因为没有 web.xml 文件。只需再类上添加@ Configuration 注释,然后添加用@Bean 注释的方法,Spring 会自动加载对象对其进行管理。甚至可以将@Autowired 添加到 bean 方法中,使 Spring 自动装入需要的依赖关系中。
    8. 基于环境的配置,可以将正在使用的环境传递到应用程序:-Dspring.profiles.active = {enviornment}。在加载主应用程序属性文件后,Spring 将在(application{environment} .properties)中加载后续的应用程序属性 文件。


      运行SpringBoot项目的方式(必会)
      SpringBoot的启动器starter(必会)

    9. starter是启动器,可以通过启动器集成其他的技术,比如说: web, mybatis, redis等.可以提供对应技术的开发和运行环境. 比如: pom中引入spring-boot-starter-web, 就可以进行web开发.

    10. starter的执行原理。SpringBoot在启动时候会去扫描jar包中的一个名为spring.factories. 根据文件中的配置去加载自动配置类. 配置文件格式是key=value, value中配置了很多需要Spring加载的 类. Spring会去加载这些自动配置类, Spring读取后,就会创建这些类的对象,放到Spring容器中.后期就会从 Spring容器中获取这些类对象.

    SpringBoot运行原理剖析(必会)

    SpringBoot中的配置文件(必会)

    1. bootstrap: yml/application application: yml/application
    2. 上面两种配置文件有什么区别?

      1. bootstrap由父ApplicationContext加载, 比application配置文件优先被加载.
        2. bootstarp里的属性不能被覆盖.
    3. application: springboot项目中的自动化配置.

    4. bootstrap:使用spring cloud config配置中心时, 需要加载连接配置中心的配置属性的, 就 可以使用 bootstrap来完成. 加载不能被覆盖的属性.加载一些加密/解密的数据.

    读取配置文件的方式?

    1. 读取默认配置文件 需要注入Environment类, 使用environment.getProperty(peorperties中的key), 这样就能获得key对应 的value值 @value(${key.value}) 直接读取
    2. 读取自定义配置文件 自定义配置文件后缀必须是.propeties 3.5 、 SpringBoot常用注解(必会) 3.6、 Spring Boot 的核心注解是哪个?它主要由哪几个注解组成的? 五、项目瑞吉点餐 1、课程业务模块总结、 2、技术栈 3、项目描述 4、职责 六 、 汇客CRM 编写和自定义配置文件对应的java类, 类上放3个注解 @ConfigurationProperties(“前缀”) @PropertySource(“指定配置文件”) @@Component包扫描 读取的时候就跟读取默认配置文件一样.

    SpringBoot支持哪些日志框架(了解)
    SpringBoot常用注解(必会)

    1. @SpringBootApplication:它封装了核心的@SpringBootConfiguration +@EnableAutoConfiguration +@ComponentScan这三个类,大大节省了程序员配置时间,这就是SpringBoot 的核心设计思想.
    2. @EnableScheduling是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器 @MapperScan:spring-boot支持mybatis组件的一个注解,通过此注解指定mybatis接口类的路径,即可完 成对mybatis接口的扫描
    3. @RestController 是@Controller 和@ResponseBody的结合,一个类被加上@RestController注解,数 据接口中就不再需要添加@ResponseBody,更加简洁。 @RequestMapping,我们都需要明确请求的路径
    4. @GetMappping,@PostMapping, @PutMapping, @DeleteMapping 结合@RequestMapping使用, 是 Rest风格的, 指定更明确的子路径.
    5. @PathVariable:路径变量注解,用{}来定义url部分的变量名. @Service这个注解用来标记业务层的组件,我们会将业务逻辑处理的类都会加上这个注解交给spring容器。 事务的切面也会配置在这一层。当让 这个注解不是一定要用。有个泛指组件的注解,当我们不能确定具体作用的时候 可以用泛指组件的注解托付给spring容器 @Component和spring的注解功能一样, 注入到IOC容器中.
    6. @ControllerAdvice 和 @ExceptionHandler 配合完成统一异常拦截处理. 备注: 面试的时候记住6.7个即可~