Spring Bean 的生命周期和作用域?
Spring Bean 的生命周期
Spring Bean 的生命周期可以分成,创建,使用,销毁几个过程。
Spring Bean 创建过程如下:
- 实例化 Bean 对象
- 设置 Bean 属性
- 通过各种 Aware 接口声明了依赖关系,则会注入 Bean 对容器基础设施层面的依赖,包括 BeanNameAware 、BeanFactoryAware 和 ApplicationContextAware 分别注入 BeanID ,BeanFactory或者ApplicationContext
- 调用 BeanPostProcessor 的前置初始化方法 postProcessBeforeInitialization
- 如果实现了InitializingBean 接口,会调用 afterPropertiesSet 方法。
- 调用 Bean 自身定义的 init 方法。
- 调用 BeanPostprocessor 的后置初始方法 postProcessAfterInitialization。
- 创建过程完毕。
Spring Bean创建过程
Spring Bean 的销毁
Spring Bean 的销毁过程会依次调用 DisposableBean 的 destroy 方法和 Bean 自身定制的 destroy() 方法。
Spring Bean 作用域
Spring Bean 有五个作用域,最基础的是如下两种:
- Singleton ,这是 Spring 的默认作用域,也就是为每个 IOC 容器创建唯一一个 Bean 实例,也称为单例。
- Prototype ,针对每个 getBean 请求,容器会单独创建一个 Bean 实例。
从 Bean 的特点来看,Prototype 适合有状态的 Bean ,而Singleton 则更适合无状态的情况。
Web 容器还支持另外三种作用域
- Request, 每个 HTTP 请求创建单独的 Bean 实例。
- Session ,很显然 Bean 实例的作用域是 Session范围。
- GlobalSession, 用于 Portlet 有单独的 Session,GlobalSession 提供了一个全局性的 HTTP Session。
Spring 基础机制
- IOC, 控制反转(Invension of Control) ,或者叫做依赖注入(Depency Injection),通过这种机制,可以有效的改善模块之间的紧耦合问题。从 Bean 创建过程可以看到,它的依赖关系都是由容器负责注入。
spring 注入的四种方式:
- 构造器注入
- setter 方法注入
- 基于注解注入
- AOP,我们是通过切面编程机制,Spring 框架中的事务、日志、安全、等功能都依赖 AOP 技术。
Spring AOP 关键概念
- Aspect , 通常叫做方面,它是跨不同 Java 类层面的横切行逻辑。在实现形式上,可以是 XML 文件中配置的普通类,也可以是 @Aspect 注解取声明。在运行时,Spring 框架会创建类似 Advisor 来指代它,其内部包括切入的时机(Pointcut)和动作 (Advide)
- Join Point 它是 Aspect 可以切入的特定点,在 Spring 里面只有方法可以作为 Join Point
- Advice ,定义了切面中能够采取的动作。
- http://aopalliance.sourceforge.net/
Spring Advice结构
BeforeAdvice 和 AfterAdvice 包括他的子类接口是简单的实现,而 Interceptor 则是所谓的拦截器,用于拦截住方法调用事件,进而采取相应动作,所以 Interceptor 是覆盖整个方法过程调用的 Advice。通常将拦截器类型的 Advice叫做 Around ,在代码中使用 @Arround 来标记。aop:around。
image
PointCut 它负责具体定义 Aspect 被应用在哪些 Joint Point 可以通过指定具体的类名和方法名来实现。
image
- Join Point 仅仅是可利用的机会
- PointCut 是解决切面变成中的 where 问题,让程序知道哪些机会点可以应用某个切面操作。
- Advice 则是明确了切面编程中的 what ,也就是做什么,同时通过指定 Before 、After 或者 Around ,定义了When ,也就是什么时候做的问题。
- https://github.com/spring-projects/spring-framework/blob/da80502ea6ed4860f5bf7b668300644cdfe3bb5a/spring-context/src/test/java/org/springframework/aop/framework/CglibProxyTests.java