ok

MVC

  • Ioc,控制反转,将对象的创建和控制权交给spring,Ioc容器
  • AOP的直接体现就是注解

AOP和IOC的理解

  1. AOP面向切面编程,起到了解耦的作用,完成一个日志/事务/权限处理等不属于业务里的功能,不需要更改过多业务代码,而是通过一个AOP动态代理(JDK/GClib)完成,调用时将公共逻辑添加到项目中
  2. IOC,控制反转+依赖注入,通过IOC容器控制对象/对象的依赖 的创建,反转是用IOC容器创建后注入到对象中,由主动创建变成了被动创建
    • IOC底层实现过程:核心原理是反射,使用BeanFactory的工厂模式实现的
    1. createBeanfactory创建bean工厂
    2. 循环创建对象,先通过getBeandoGetBean从容器中查找,没有的话去createBean,doGreateBean,以反射的方法创建对象
    3. 进行对象的属性填充populateBean和进行其他初始化initializingBean

      Bean的生命周期

  3. 反射的方式实例化Bean
  4. 对象属性用populateBean填充,循环依赖使用三级缓存
  5. invokeAwareMethod,设置相关依赖:BeanName BeanFactory BeanClassloader
  6. 调用BeanPostProcessor()前置处理方法,ApplicationContextPostPostProcessor,设置上下文,环境,resourceloader等对象
  7. 调用invokeInitmethod(),判断是否实现initializingBean,调用了就再调用afterpropertiesSet方法
  8. 调用BeanPostProcessor的后置处理方法,AOP在该过程实现,AbstractAutoProxyCreator(),advice切面切点
  9. 获取完整的对象,可以用getbean获取了
  10. 执行完后,销毁流程,先判断是否实现DisposableBean接口,再判断是否实现DestroyMethod接口

循环依赖怎么解决?【使用了三级缓存】

使用了三级缓存,AOP,提前暴露对象

  1. 问题:对象循环依赖产生的问题,A依赖B,B依赖A,提前暴露对象导致的
  2. Bean创建流程是先实例化,再进行属性填充初始化
  3. A如果属性里有B,在填充时需要从IOC容器里查找B,找不到的话,就创建B;然后B在属性填充的时候查找A,但是A没有创建完毕,
  4. 一级缓存中放的是完整对象,二级是没有完全创建的对象
  5. 第三级为什么需要?第三级缓存的value类型是ObjectFactory类型的函数接口,保证在整个容器的作用域中只有一个版本的同名Bean对象。
  6. 创建bean对象后,要放到三级缓存中是用于先判断是否需要被代理,选择取的是普通对象还是代理对象。

如果一个对象需要被代理,需不需要先实例化一个普通对象(要,必须传参数给wrapifnecessary)

普通对象和代理对象不能同时出现在容器中,当需要被代理时,就需要覆盖普通对象

SpringAOP的底层原理

底层原理就是使用的jvm或者gclibs的动态代理功能。AOP的实现阶段是IOC的BeanPostProcessor的后置方法中实现的扩展功能。

  1. 介绍一下jvm gclib的原理,反射

Spring的设计模式

  1. Bean都是单例模式
  2. 工厂模式,BeanFactory
  3. 观察者模式,Listener,Event
  4. 适配器模式,Adapter
  5. 装饰者模式:Bean的Wrapper
  6. 责任链模式:使用AOP时,先生成一个拦截器
  7. 代理模式:AOP使用的动态代理

    事务

    Spring事务如何实现的,如何回滚

    答:事务是AOP实现的声明式事务。也就是首先要生成具体的代理对象,按AOP的流程来执行具体操作逻辑。
    1
    2
    @Transactional(propagation = Propagation.REQUIRED,
    isolation = Isolation.DEFAULT, readOnly = false, timeout = -1)

底层具体到代码里是用jdbc的datasourceTransactionManager实现的,注解声明的事务逻辑是通过一个TransationInterceptor类实现,调用invoke函数体里,最后返回一个invokewithtransaction实现具体逻辑(对传参的方法使用getmethod获取)

  • 回滚的方式如下:
  1. 执行失败使用completeTransactionAfterthrowing
  2. 执行成功用completeTransactionAfterreturning
  3. 执行失败的回滚在transactional的doRollback里实现,里面是先获取object.getconn连接,然后conn.rollback回滚,只对于这个特定连接进行,而不是全局的。
  4. 执行成功的提交在transactional里的doCommit,也是获取连接,用jdbc连接的conn.commit()方法提交。
  5. 最后cleanTransactionInfo清除当前事务信息

SpringBoot的优点

  1. 独立运行
    Spring Boot 而且内嵌了各种 servlet 容器,Tomcat、Jetty 等,现在不再需要打成war 包部署到容器中,Spring Boot 只要打成一个可执行的 jar 包就能独立运行,所有的依赖包都在一个 jar 包内。
  2. 简化配置
    spring-boot-starter-web 启动器自动依赖其他组件,简少了 maven 的配置。
  3. 自动配置
    Spring Boot 能根据当前类路径下的类、jar 包来自动配置 bean,如添加一个 spring
    boot-starter-web 启动器就能拥有 web 的功能,无需其他配置。
  4. 无代码生成和XML配置
    Spring Boot 配置过程中无代码生成,也无需 XML 配置文件就能完成所有配置工作,这一切都是借助于条件注解完成的,这也是 Spring4.x 的核心功能之一。
  5. 应用监控
    Spring Boot 提供一系列端点可以监控服务及应用,做健康检测

    Spring Bean

    被Ioc容器管理的对象,通过xml或者Entity等注解
  • org.springframework.beans

  • org.springframework.context

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

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

  • @Service : 对应服务层,主要涉及一些复杂的逻辑,需要用到 Dao 层。

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

1. @Bean和@Component的区别

  1. bean用于方法,component用于注解
  2. @Component通常是通过类路径扫描来自动侦测以及自动装配到 Spring 容器中(我们可以使用 @ComponentScan 注解定义要扫描的路径从中找出标识了需要装配的类自动装配到 Spring 的 bean 容器中)。
  3. @Bean注解通常是我们在标有该注解的方法中定义产生这个 bean,@Bean告诉了 Spring 这是某个类的实例,当我需要用它的时候还给我

    2. 可以注入Bean的注解有哪些

  4. @Autowired
  5. @Resource

Spring事务

Spring 管理事务的方式有几种?

  • 编程式事务:在代码中硬编码(不推荐使用) : 通过 TransactionTemplate或者 TransactionManager 手动管理事务,实际应用中很少使用,但是对于你理解 Spring 事务管理原理有帮助。
  • 声明式事务:在 XML 配置文件中配置或者直接基于注解(推荐使用) : 实际是通过 AOP 实现(基于@Transactional 的全注解方式使用最多)

1. @Transactional

使用场景:hibernate的删除事务,更新事务

  • 使用@Transactional(rollbackFor = Exception.class)
    • 用于保证事务一致性,发生异常时回滚
    • 不配置for exception的话,只有在runtime err时回滚,为了保证可靠性

SpringBoot

  1. 从常用注解和生命周期,启动,监控,测试等考察
  2. 是@Configuration、@EnableAutoConfiguration、@ComponentScan的集合体

1. @SpringBootApplication

自动装配原理是什么?

  1. @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  2. @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类
  3. @ComponentScan:扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描启动类所在的包下所有的类 ,可以自定义不扫描某些 bean。

2. 常用注解:

  1. @RestController和@Controller指定一个类,作为控制器的注解
  2. @RequestMapping方法级别的映射注解,这一个用过Spring MVC的小伙伴相信都很熟悉
  3. @EnableAutoConfiguration和@SpringBootApplication是类级别的注解,根据maven依赖的jar来自动猜测完成正确的spring的对应配置,只要引入了spring-boot-starter-web的依赖,默认会自动配置Spring MVC和tomcat容器
  4. @Configuration类级别的注解,一般这个注解,我们用来标识main方法所在的类,完成元数据bean的初始化。
  5. @ComponentScan类级别的注解,自动扫描加载所有的Spring组件包括Bean注入,一般用在main方法所在的类上
  6. @ImportResource类级别注解,当我们必须使用一个xml的配置时,使用@ImportResource和@Configuration来标识这个文件资源的类。
  7. @Autowired注解,一般结合@ComponentScan注解,来自动注入一个Service或Dao级别的Bean
  8. @Component类级别注解,用来标识一个组件,比如我自定了一个filter,则需要此注解标识之后,Spring Boot才会正确识别。

面试问题

1.BeanFactory

2.常用注解