0701 - Spring Framework
2021-05-12 23:07:43 0 举报
AI智能生成
系统架构、Java技术栈、面试宝典
作者其他创作
大纲/内容
Spring
ContextLoaderListener监听器
是整个Spring应用启动的关键
Spring启动过程大致如下:
1、在Servlet容器启动后,会创建一个ServletContext(整个Web应用的上下文);
2、由于ContextLoaderListener实现了ServletContextListener,因此会在ServletContext创建完成后,其中的contextInitialized方法会自动被调用;contextInitialized方法将通过ServletContext实例的getParameter()方法找到Spring配置文件位置,然后根据其中的内容为Spring创建一个根上下文(WebApplicationContext,即通常所说的IOC容器);
3、将WebApplicatonContext作为ServletContext的一个属性放进去,名称是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。
1、在Servlet容器启动后,会创建一个ServletContext(整个Web应用的上下文);
2、由于ContextLoaderListener实现了ServletContextListener,因此会在ServletContext创建完成后,其中的contextInitialized方法会自动被调用;contextInitialized方法将通过ServletContext实例的getParameter()方法找到Spring配置文件位置,然后根据其中的内容为Spring创建一个根上下文(WebApplicationContext,即通常所说的IOC容器);
3、将WebApplicatonContext作为ServletContext的一个属性放进去,名称是WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE。
Spring IOC
定义
WebApplicationContext:即Spring IOC容器,由容器创建和管理Bean,使用时直接从容器中获得
配置方式
XML配置文件
@Resource/@Autowired注解配置
Bean的作用域
Spring支持如下5种作用域(见ConfigurationBeanFactory和WebApplicationContext接口源码):
(1)singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;
(2)prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例;
(3)request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,只有在Web应用中使用Spring时,该作用域才有效;
(4)session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效;
(5)globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet; *context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效。
(1)singleton:单例模式,在整个Spring IoC容器中,使用singleton定义的Bean将只有一个实例;
(2)prototype:原型模式,每次通过容器的getBean方法获取prototype定义的Bean时,都将产生一个新的Bean实例;
(3)request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例,只有在Web应用中使用Spring时,该作用域才有效;
(4)session:对于每次HTTP Session,使用session定义的Bean都将产生一个新实例。同样只有在Web应用中使用Spring时,该作用域才有效;
(5)globalsession:每个全局的HTTP Session,使用session定义的Bean都将产生一个新实例。典型情况下,仅在使用portlet; *context的时候有效。同样只有在Web应用中使用Spring时,该作用域才有效。
依赖注入的几种方式
构造注入
属性注入setter
静态工厂注入
接口注入
理解Spring IOC容器设计原理
Bean的生命周期
实例化
实例化一个Bean,也就是我们常说的new
IOC依赖注入
按照Spring上下文对实例化的Bean进行配置,也就是IOC注入
setBeanName实现
如果这个Bean 已经实现了BeanNameAware 接口,会调用它实现的setBeanName(String)方法,
此处传递的就是Spring 配置文件中Bean 的id 值
此处传递的就是Spring 配置文件中Bean 的id 值
BeanFactoryAware实现
如果这个Bean 已经实现了BeanFactoryAware 接口,会调用它实现的setBeanFactory,
setBeanFactory(BeanFactory)传递的是Spring 工厂自身(可以用这个方式来获取其它Bean,
只需在Spring 配置文件中配置一个普通的Bean 就可以)
setBeanFactory(BeanFactory)传递的是Spring 工厂自身(可以用这个方式来获取其它Bean,
只需在Spring 配置文件中配置一个普通的Bean 就可以)
ApplicationContextAware实现
如果这个Bean 已经实现了ApplicationContextAware 接口,会调用
setApplicationContext(ApplicationContext)方法,传入Spring 上下文(同样这个方式也
可以实现步骤4 的内容,但比4 更好,因为ApplicationContext 是BeanFactory 的子接口,
有更多的实现方法)
setApplicationContext(ApplicationContext)方法,传入Spring 上下文(同样这个方式也
可以实现步骤4 的内容,但比4 更好,因为ApplicationContext 是BeanFactory 的子接口,
有更多的实现方法)
postProcessBeforeInitialization接口实现-初始化预处理
如果这个Bean 关联了BeanPostProcessor 接口,将会调用postProcessBeforeInitialization(Object obj, String s)
方法,BeanPostProcessor 经常被用作是Bean 内容的更改,并且由于这个是在Bean 初始化结束时调用那个的方法,
也可以被应用于内存或缓存技术。
方法,BeanPostProcessor 经常被用作是Bean 内容的更改,并且由于这个是在Bean 初始化结束时调用那个的方法,
也可以被应用于内存或缓存技术。
init-method
如果Bean 在Spring 配置文件中配置了init-method 属性会自动调用其配置的初始化方法
postProcessAfterInitialization
如果这个Bean 关联了BeanPostProcessor 接口,将会调用postProcessAfterInitialization(Object obj, String s)方法。
注:以上工作完成以后就可以应用这个Bean 了,那这个Bean 是一个Singleton 的,所以一般情况下我们调用同一个id
的Bean 会是在内容地址相同的实例,当然在Spring 配置文件中也可以配置非Singleton。
注:以上工作完成以后就可以应用这个Bean 了,那这个Bean 是一个Singleton 的,所以一般情况下我们调用同一个id
的Bean 会是在内容地址相同的实例,当然在Spring 配置文件中也可以配置非Singleton。
Destroy过期清理阶段
当Bean 不再需要时,会经过清理阶段,如果Bean 实现了DisposableBean 这个接口,会调用那个其实现的destroy()方法
destroy-method子配置清理
最后,如果这个Bean 的Spring 配置中配置了destroy-method 属性,会自动调用其配置的销毁方法
-------------------------------------------------------------------------------------------------------
bean标签有两个重要的属性(init-method 和destroy-method)。用它们你可以自己定制初始化和
注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy)。
<bean id="" class="" init-method="初始化方法" destroy-method="销毁方法">
-------------------------------------------------------------------------------------------------------
bean标签有两个重要的属性(init-method 和destroy-method)。用它们你可以自己定制初始化和
注销方法。它们也有相应的注解(@PostConstruct 和@PreDestroy)。
<bean id="" class="" init-method="初始化方法" destroy-method="销毁方法">
Spring Context装载过程分析
FactoryBean与BeanFactory区别
Spring AOP
AOP两种代理方式
Spring 提供了两种方式来生成代理对象: JDKProxy 和Cglib,具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport
对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK 动态代理技术,否则使用Cglib 来生成代理。
对象的配置来决定。默认的策略是如果目标类是接口,则使用JDK 动态代理技术,否则使用Cglib 来生成代理。
JDK动态代理(针对接口,代理类为其兄弟类)
JDK 动态代理主要涉及到java.lang.reflect 包中的两个类:Proxy 和InvocationHandler。
InvocationHandler 是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类
的代码,动态将横切逻辑和业务逻辑编制在一起。Proxy 利用InvocationHandler 动态创建
一个符合某一接口的实例,生成目标类的代理对象。
InvocationHandler 是一个接口,通过实现该接口定义横切逻辑,并通过反射机制调用目标类
的代码,动态将横切逻辑和业务逻辑编制在一起。Proxy 利用InvocationHandler 动态创建
一个符合某一接口的实例,生成目标类的代理对象。
CGLIB动态代理(针对类,代理类为其子类)
CGLib 全称为Code Generation Library,是一个强大的高性能,高质量的代码生成类库,
可以在运行期扩展Java 类与实现Java 接口,CGLib 封装了asm,可以再运行期动态生成新
的class。和JDK 动态代理相比较:JDK 创建代理有一个限制,就是只能为接口创建代理实例,
而对于没有通过接口定义业务方法的类,则可以通过CGLib 创建动态代理。
可以在运行期扩展Java 类与实现Java 接口,CGLib 封装了asm,可以再运行期动态生成新
的class。和JDK 动态代理相比较:JDK 创建代理有一个限制,就是只能为接口创建代理实例,
而对于没有通过接口定义业务方法的类,则可以通过CGLib 创建动态代理。
拦截器
掌握Spring AOP编程概念
AOP注解编程
@EnableAspectJAutoProxy
@Before/@After/@AfterReturning/@AfterThrowing/@Around
@Pointcut
基于Spring Aop实现应用插件机制
Spring AOP源码解析
ProxyFactory源码解析
AOP代理源码解析
连接器与织入源码解析
SPring事务控制与底层源码分析
@EnableTransactionManagement源码剖析
@Transaction源码剖析
事务管理
五大事务隔离级别
事务的隔离级别是为了防止脏读、不可重复读、幻读问题的发生。 ----------------------------------------------------------------------------------------------------------
ISOLATION_DEFAULT :使用后端数据库默认的隔离级别。
ISOLATIONREADUNCOMMITTED :允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。
ISOLATIONREADCOMMITTED :允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。
ISOLATIONREPEATABLEREAD :对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。
ISOLATION_SERIALIZABLE :完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。
ISOLATION_DEFAULT :使用后端数据库默认的隔离级别。
ISOLATIONREADUNCOMMITTED :允许读取尚未提交的更改。可能导致脏读、幻读或不可重复读。
ISOLATIONREADCOMMITTED :允许从已经提交的并发事务读取。可防止脏读,但幻影读和不可重复读仍可能会发生。
ISOLATIONREPEATABLEREAD :对相同字段的多次读取的结果是一致的,除非数据被当前事务本身改变。可防止脏读和不可重复读,但幻影读仍可能发生。
ISOLATION_SERIALIZABLE :完全服从ACID的隔离级别,确保不发生脏读、不可重复读和幻读。这在所有隔离级别中也是最慢的,因为它通常是通过完全锁定当前事务所涉及的数据表来完成的。
七大事务传播属性
Spring在TransactionDefinition接口中定义了7种类型的事务传播行为,它们规定了事务方法间发生嵌套调用时事务如何进行传播。
------------------------------------------------------------------------------------------------------------
PROPAGATION_MANDATORY :表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常
PROPAGATIONNESTED :表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATIONREQUIRES一样。
PROPAGATION_NEVER :表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。
PROPAGATIONNOTSUPPORTED:表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。
PROPAGATION_SUPPORTS :如果当前方法在一个事务中,则以事务的形式运行;如果当前不再一个事务中,那么就以非事务的形式运行。
PROPAGATIONREQUIRESNEW :表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。
PROPAGATION_REQUIRES :表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。
------------------------------------------------------------------------------------------------------------
PROPAGATION_MANDATORY :表示该方法必须运行在一个事务中。如果当前没有事务正在发生,将抛出一个异常
PROPAGATIONNESTED :表示如果当前正有一个事务在进行中,则该方法应当运行在一个嵌套式事务中。被嵌套的事务可以独立于封装事务进行提交或回滚。如果封装事务不存在,行为就像PROPAGATIONREQUIRES一样。
PROPAGATION_NEVER :表示当前的方法不应该在一个事务中运行。如果一个事务正在进行,则会抛出一个异常。
PROPAGATIONNOTSUPPORTED:表示该方法不应该在一个事务中运行。如果一个现有事务正在进行中,它将在该方法的运行期间被挂起。
PROPAGATION_SUPPORTS :如果当前方法在一个事务中,则以事务的形式运行;如果当前不再一个事务中,那么就以非事务的形式运行。
PROPAGATIONREQUIRESNEW :表示当前方法必须在它自己的事务里运行。一个新的事务将被启动,而且如果有一个现有事务在运行的话,则将在这个方法运行期间被挂起。
PROPAGATION_REQUIRES :表示当前方法必须在一个事务中运行。如果一个现有事务正在进行中,该方法将在那个事务中运行,否则就要开始一个新事务。
事务管理器
核心接口PlatformTransactionManager
编程式事务
通过使用TransactionTemplate或者PlatformTransactionManager相关事务API来实现事务管理
声明式事务
XML配置<tx:advice>标签
@Transactional标签
异常回滚
只会回滚RuntimeException异常
定时任务调度Spring Task
XML配置<task:scheduler>标签
@Scheduled注解配置
异步任务
XML配置<task:executor>标签
@Async注解配置
缓存支持Spring Cache
Spring注解式开发
@Bean/@ComponentScan/@Configuration/@Conditional
@Component/@Service/@Controller/@Repository
@Lazy/@Scope/@Import/@Value/@Profile
@Autowired/@Resources/@Inject
Spring5.0 新特性
兼容Java9
响应式编程模型
响应式编程WebFlux
概念
即Spring-WebFlux模块,以Reactor库为基础,包含了对响应式Http、服务器推送事件(Server-Sent Event)和WebSocket的客户端和服务端的支持。
基于Java注解编程模型
使用方式和SpringMVC基本一样,只是使用的类型不是普通的对象,而是响应式编程中的Mono、Flux对象
Mono对象:表示单个对象,如User用法与Optional类似
Flux对象:表示一系列的对象,类似于List<User>
基于函数式编程基础
服务器端
HandlerFunction函数式接口
Mono<T extends ServerResponse> handle(ServerRequest request)方法用于处理客户端请求
RouterFunction路由接口
Mono<HandlerFunction<T enxtends ServerResponse>> route(ServerRequest request)方法用于选择处理对应请求的HandlerFunction对象并返回
客户端
使用WebClient.create方法创建客户端发起HTTP请求调用REST API和SSE(服务端推送)服务
使用WebSocketClient类的API访问WebSocket
测试
使用WebTestClient类进行测试
函数式风格的ApplicationContext
Kotlin表达式的支持
面试考察点
首先要掌握 Spring 的核心概念 IoC、AOP 以及具体的实现方式
要重点掌握 SpringContext 的初始化流程、Bean 的生命周期
0 条评论
下一页