Spring Bean的作用域
- singleton: Spring的默认作用域,容器里拥有
唯一的Bean
实例,适合无状态的Bean. - prototype: 针对
每个getBean请求, 容器都会创建一个Bean对象
,适合有状态的Bean. - request: 会为
每个Http请求创建一个Bean实例
,该作用域只针对web容器有效. - session: 会为
每个session创建一个Bean实例
,该作用域只针对web容器有效. - globalSession: 会
为每个全局HttpSession创建一个Bean实例
,该作用域仅对Portlet这个web容器有效.
Spring Bean的生命周期,这个我没怎么整明白,大家瞄一眼就好了
创建过程:
销毁过程:
Spring AOP概念
软件有一个基本原则,那就是关注点分离, 即将不同的问题交给不同的部分去解决
,每个部分只专注于自己的问题.
- 面向切面编程AOP,正好是一种
体现了这种原则的技术
,我们的代码主要就是用于实现某种特定的业务逻辑,但是同时我们还需要实现一些通用化功能比如事务管理,日志记录
等与业务功能组合在一起. - 为了将业务功能的关注点和通用化功能的关注点分离开来,就出现了AOP技术,其中
通用化功能代码的实现对应的就是所谓的切面(Aspect)
. - 业务功能代码和切面代码分开之后,架构将变得高内聚,低耦合.
- 代码分开的同时,我们还需要保证功能的完整性, 所以说
切面最终需要被合并到业务中(即Weave 织入过程)
.
AOP的三种织入方式
- 编译时织入: 即在代码编译时就把切面代码融合到业务代码中生成完整功能的java字节码文件,这样的实现需要特殊的java编译器,比如
AspectJ
. - 类加载时织入: 即在业务逻辑的字节码加载的时候,将切面的字节码融入进去,这同样需要特殊的java编译器,比如
AspectJ
和AspectWerkz
. - 运行时织入: 即在运行时通过动态代理的方式调用
切面代码增强业务功能
,Spring就是采用的这种方式,虽然采用动态代理会有额外的开销,但是不需要特殊的编译器.
AOP的几个名词
Advice的种类
AOP的实现: JdkProxy和Cglib
- 具体使用哪种方式生成由AopProxyFactory根据AdvisedSupport对象的配置来决定.
- 默认的策略: 如果目标类是接口,则使用jdk动态代理来实现,否则使用后者.
- jdk动态代理通过反射来接收被代理的类,同时该类必须实现InvocationHandler接口,其核心为:
InvocationHandler接口
和Proxy类
,关于如何使用动态代理见 动态代理 这篇博客. - Cglib(Code generation library,理解为代码生成类库): 它可以在运行时动态生成某个类的子类,通过修改字节码文件实现,注意它是以继承的方式动态的生成目标类的代理,如果某个类标记为final,那么无法使用Cglib做代理.
JDKProxy
通过java内部反射机制来实现的,在生成类的过程中比较高效.
Cglib
借助ASM实现,ASM是一种能够操纵字节码的框架,在生成类之后的执行过程中比较高效.
代理模式
代理模式的组成:
接口 + 真实实现类 + 代理类
其中真实实现类和代理类都是要实现前面的接口
的.
Spring AOP需要做的就是生成一个代理类来替换掉真实实现类以对外提供服务
.
Spring中的代理模式的实现
- 真实实现类的逻辑包含在了getBean方法里.
- getBean方法返回的实际上是Proxy的实例.
- Proxy实例是Spring采用JDK Proxy或CGLIB动态生成的.