1 Spring事务传播机制
事务传播机制是事务方法和事务方法嵌套时 Spring 采用的事务传递规则;
Spring定义的7个事务传播规则如下:
PROPAGATION_REQUIRED 如果当前没有事务,则新建一个事务. 如果当前有事务,则加入;
PROPAGATION_SUPPORTS 支持当前事务, 如果当前没有事务,就以非事务方式运行;
PROPAGATION_MANDATORY 使用当前事务, 如果没有事务, 就抛出异常;
PROPAGATION_REQUIRES_NEW 新建事务, 如果当前存在事务, 就把当前事务挂起;
PROPAGATION_NOT_SUPPORTED 以非事务方式执行,如果当前存在事务,就把当前事务挂起;
PROPAGATION_NEVER 以非事务方式执行, 如果当前存在事务, 就抛异常;
PROPAGATION_NESTED 嵌套事务,如果当前存在事务则在嵌套事务内执行;如果没有事务,则新建一个;
2 SpringAOP原理
SpringAOP 面向切面编程, 可以允许用户在程序运行过程中, 动态的加入自己想要执行的功能;如日志记录,性能监控等;
原理:
基于动态代理实现AOP,动态代理有JDK动态代理和CGLIB动态代理两种
JDK动态代理的实现机制要求被代理的类必须实现接口, 然后生成接口的实现类来实现动态代理
CGLIB可以允许任何类实现动态代理,其原理是在程序运行过程中动态的生成该类的代理类
两种代理除了生成代理类的方式不同,其原理是一样的:
都是在生成的代理类中调用invoke方法,调用原来类中的方法, 而且在调用该方法的前后都添加了相应的功能代码,这样就实现了 动态的织入功能
作用
有些问题是面向对象的思想解决不了的, 在一些方法前后执行一些事情
使用场景
事务管理,权限控制,日志记录,性能监控
3 Spring IoC和DI
IoC(控制反转),是Spring容器的内核,原先由程序员自维护的对象与关系,托付给spring容器,由spring来负责控制对象的生命周期和维护对象间的关系。它的实现原理,通过注解或者bean配置获取类全限类名,反射生成需要的bean对象。
DI(依赖注入),spring在创建对象过程中将对象所依赖的所有依赖关系,根据bean配置,setter到对象里。本质上是spring调用对象的setter、构造器,初始化对象。
3.1 Spring Bean的注入方式
- set()注入
- 构造器注入
- 静态工厂
- 实例工厂
Spring中Bean的注入
3.2 如果两个甚至多个Bean有循环依赖,其注入方式可选哪种?
循环依赖的场景中,构造器注入和prototype类型(每次对bean的请求都会创建一个新的实例)的属性注入都是初始化Bean失败. 但是单例的属性注入是可以成功的.而且,Spring中默认的Bean的创建就是单例的
以上四种除了构造器注入都可以
**Spring在InstantiateBean时执行构造器方法,构造出实例,如果是单例的话,会将它放入一个singletonBeanFactory的缓存中,再进行populateBean方法,设置属性。通过一个singletonBeanFactory的缓存解决了循环依赖的问题。
**
Spring如何解决循环依赖问题的
4 Spring Bean的生命周期
生命周期
- 实例化 Instantiation
- 属性赋值 Populate
- 初始化 Initialization
- 销毁 Destruction
请别再问SPring Bean的生命周期了
5 Spring自定义注解实现方式
- 首先创建自定义注解 xxxAnnotation
- 创建切面类,通过
@Aspect
注解,使创建的类成为切面类 - 在切面类中通过
@Pointcut
指定切入点(此处切入点为xxxAnnotation) @Before
前置通知@Around
环绕通知@AfterReturning
后置通知@AfterThrowing
异常通知
6 SpringMVC的工作流程
- 用户发送请求至前端控制器DispatcherServlet。
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
- DispatcherServlet调用HandlerAdapter处理器适配器。
- HandlerAdapter经过适配调用具体的处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView。
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet。
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器。
- ViewReslover解析后返回具体View.
- DispatcherServlet根据View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户。
7 SpringBoot 启动类上的注解
我们在新生成一个SpringBoot项目的时候, 在其启动类中会有一个注解@SpringBootApplication
它是多个注解的组合注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
}
其中最重要的三个@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan
分别表示
@SpringBootConfiguration
它就是JavaConfig形式的Spring Ioc容器的配置类。被标注的类等于在spring的XML配置文件中(applicationContext.xml),装配所有bean事务,提供了一个spring的上下文环境。@EnableAutoConfiguration
SpringBoot根据应用所声明的依赖来对Spring框架进行自动配置。简单概括一下就是,是借助@Import的帮助,将所有符合自动配置条件的bean定义加载到IoC容器。@ComponentScan
组件扫描,可自动发现和装配Bean,功能其实就是自动扫描并加载符合条件的组件或者bean定义,最终将这些bean定义加载到IoC容器中。可以通过basePackages等属性来细粒度的定制@ComponentScan自动扫描的范围,如果不指定,则默认Spring框架实现会从声明@ComponentScan所在类的package进行扫描。默认扫描SpringApplication的run方法里的Booter.class所在的包路径下文件,所以最好将该启动类放到根包路径下。
8 SpringBoot start 运行机制
SpringBoot启动的时候,会构造一个SpringApplication的实例,然后调用这个实例的run方法,这样就表示启动SpringBoot。
在run方法调用之前,也就是构造SpringApplication的时候会进行初始化的工作,会调用一个private类型的initialize方法
- 把参数sources设置到SpringApplication属性中, 这个sources可以是任何类型的参数;
- 判断是否是web程序, 并设置到webEnvironment这个boolean属性中;
- 找出所有的初始化器, 默认有5个, 设置到initializers属性中;
- 找出所有的应用程序监听器,默认有9个,设置到listeners属性中;
- 找出运行的主类(main class);
SpringApplication构造完成之后调用run方法, 启动SpringApplication, run方法执行的时候会做以下几件事:
- 构造一个StopWatch 观察SpringApplication的执行;
- 找出所有的SpringApplicationRunListener并封装到SpringApplicationRunListeners中,用于监听run方法的执行,监听的过程中会封装成事件并广播出去让初始化过程中产生的应用程序监听器进行监听;
- 构造Spring容器(ApplicationContext),并返回;
3.1 创建Spring容器的判断是否是web环境, 是的话构造AnnotationConfigEmbeddedWebApplicationContext, 否则构造 AnnotationConfigApplicationContext
3.2 初始化过程中产生的初始化器在这个时候开始工作;
3.3 Spring容器的刷新(完成bean的解析,各种processor接口的执行,条件注解的解析等等). - 从Spring容器中找出ApplicationRunner和CommandLineRunner接口的实现类并排序后依次执行;
- 通告finished();
- 结束