在这篇专栏啊,切换一下思路,只想说,现在或许我们常用的spring框架都是SpringBoot了,因为确实是好用,但是不得不说,仅仅是使用的层次,10天就完全可以达到了,所以其实没什么可以骄傲的,spring是整个spring Collections的基础,所以,这篇专栏将主要围绕spring 的底层去讨论一下spring框架的设计细节。
简述
springBean的生命周期可以分为创建和销毁两个部分:
第一,创建Bean会经过一系列的步骤,主要包括:
- 实例化Bean对象
- 设置Bean属性
- 注入Bean对容器的依赖
- 调用BeanPostProcessor的前置初始化方法postProcessBeforeInitialization
- 如果实现了InitializlingBean接口,则会调用afterPropertiesSet方法
- 调用Bean自身定义的init方法
- 调用BeanPostProcessor的后置方法postProcessAfterInitialization
- 创建过程完毕
第二,SpringBean的销毁会依次调用DisposableBean的destroy方法和Bean自身定制的destroy方法。
Spring Bean有五个作用域,其中最基础的有下面两种:
- Singleton,这是Spring的默认作用域,也就是为每个IOC容器创建唯一的一个Bean实例。
- Prototype,针对每个getBean请求,容器都会单独创建一个Bean实例。
从Bean的特点来看,Prototype适合有状态的Bean,而Singleton则更适合无状态的情况。另外,使用Prototype作用域需要经过仔细思考,毕竟频繁创建和销毁bean是有明显的开销的。
如果Web容器,则支持另外三种作用域:
- Request,为每一个HTTP请求创建单独的Bean实例
- Session,很显然Bean实例的作用域是Session范围
- GlobalSession,用于Portlet容器,因为每个Portlet有单独的Session,GlobalSession提供了一个全局性的HTTP Session。
考点分析
你可以了解到,Bean的生命周期是完全被容器所管理的,从属性设置到各种依赖关系,都是容器负责注入,并且进行各个阶段其他事宜的处理
接下来我们会解决三个热点问题:
- Spring的基础机制
- Spring框架的涵盖范围
- Spring AOP自身设计的一些细节
知识讲解
第一,来看看Spring的基础机制,至少需要理解下面两个基本方面。
-
控制反转(Inversion Of Control),或者也叫依赖注入(Dependency Injection),广泛应用于Spring框架之中,可以有效地改善了模块之间的紧耦合问题。从Bean创建的过程就知道了,它的依赖关系都是由容器负责注入,具体实现方式包括带参数的构造函数、setter方法或者Autowired方式实现。
-
AOP,我们已经在前面接触过这种切面编程机制,Spring框架中的事务、安全、日志等功能都依赖于AOP技术,下面会进一步介绍。
第二,Spring到底是指什么?
前面说到的Spring,其实也就是狭义的Spring Framework,其内部包含了IOC,Transient机制,OR Mapping等功能组成的数据访问模块,以及Spring MVC等Web框架和其他基础组件。
广义上的Spring已经成为了一个庞大的生态系统
- Spring Boot,超高级的封装,封装到了debug的时候找到源码能开几十个.java
- SpringCloud,比SpringBoot还能封,加入了分布式Web开发需要用的功能,底层基于http,添加了服务注册,配置管理,负载均衡,分布式诊断等各种子系统,可以简化微服务化的构建。
- 当然,还有针对特定领域的Spring Security,SpringData等。
说实话,不写项目,光说这个没啥用。
第三,讨论一下更多关于Spring AOP自身设计和实现的细节。
先问一下自己,我们为什么需要面向切面编程呢?
切面编程落实到软件工程其实是为了更好的模块化,而不仅仅是为了减少重复代码,通过AOP等机制,我们可以把横跨多个不同模块的代码抽离出来,让模块本身变得更加内聚,进而业务开发者可以更加专注于业务逻辑本身。
之前我们也说过了,AOP Proxy的技术使用的是JDK的动态代理或者是cglib字节码操作技术,运行的时候动态生成被调用类型的子类等,并且实例化代理对象,实际的方法调用会被代理给相应的代理对象。但是,这并没有解释具体在AOP设计层面,什么是切面,如何定义切面和切面行为。
Spring AOP通常会引入几个关键概念:
- @Aspect 在实现形式上,这个也可以被xml的配置取代,然后Spring就会创建Advisor指代。
- Join Point,它是Aspect可以切入的特定点,在Spring里,只有被@Aspect标记的方法才能作为Join Point
- Advice,定义切面中能够采取的动作,但并不是注解,只是一种概念。
具体的Spring Advice结构请参考下面的示意图。
其中,BeforeAdvice和AfterAdvice包括他们的子接口是最简单的实现。而Interceptor则是所谓的拦截器,用于拦截住方法调用事件,进而才去相应动作,所以Interceptor是覆盖住整个方法调用过程的Advice。通常将拦截器类型的Advice叫做Around,在代码中可以使用**@Around**标记。
- PointCut,负责定义@Aspect被应用在哪些JoinPoint,可以指定具体的类名和方法名来实现,或者可以使用正则来定义条件。
- JoinPoint仅仅是可利用的机会。
- Pointcut是解决了切面编程的where问题,让程序员知道哪个机会点可以用用那个软件。
- Advice明确切面编程的what,也就是做什么,同时指定出Before、After或者Around,定义了When,也就是什么时候做。