1 ioc
控制反转和依赖注入,把对象的构造、依赖管理的控制权从用户代码中反转到spring容器中,由容器来管理复杂的对象和对象之间的关系。
http://www.iteye.com/magazines/71
2 接口
ioc容器的最基础的功能规范由BeanFactory接口所定义,他规定了容器要做的最基本的事情,比如getBean方法。还有一个常用的是ApplicationContext,他在BeanFactory的基础上提供了更丰富的方法:
支持不同的信息源,支持国际化的实现
访问资源,体现在对ResourceLoader和Resource的支持上,可以从不同的地方得到bean的定义资源。
支持应用事件,他继承了ApplicationEventPublisher,在上下文中引入了事件机制,这些事件可以和bean的生命周期结合起来,为bean的管理提供便利
由于他的功能较为丰富,一般在做应用开发时,以ApplicationContext作为ioc的基础是个明智的选择。
3 ioc容器的初始化
BeanDefinition的资源定位,由ResourceLoader通过统一的接口Resource来完成,为各种形式的资源定位提供统一接口。比如有的是通过文件系统来定位,有的是通过classpath来定位。
BeanDefinition的载入,即把资源文件中的信息,载入到容器的数据结构中。容器通过这个bean的抽象来管理bean。
注册BeanDefinition,容器通过一个hashmap来维护已注册的bean定义。
在refresh方法里面包含了bean的初始化过程的模板。一般来说,在ioc的初始化过程,并不包含bean的依赖注入。
4 依赖注入
一般来说,在用户调用getBean方法的时候,才会触发依赖注入。首先会创建这个bean的时候,可能会采用反射或者cglib的机制来实例化bean。当前bean创建好之后,在通过BeanDefinition的信息,递归的调用getBean实例化他的依赖bean,并注入,最终完成当前bean的完整创建。
5 扩展点
FactoryBean是一种工厂bean,这种bean本身是一个工厂,可以生产出其他bean。通过这种特性,可以为应用生成一些特殊的bean,例如ProxyFactoryBean。他提供了一个很好的封装机制,可以封装proxy,rmi,jndi等
BeanPostProcessor bean后处理器,可以允许bean监听一些容器事件,在事件发生时触发一些后续的操作。可以是一些前置的、或者扫尾的工作。
6 AOP
AOP基于的是代理模式,而且是动态代理的模式。在spring的实现中,通过jdk内置的动态代理机制、反射机制、cglib库以及自身的ioc工厂bean的特性来实现AOP。每个对目标方法的调用都会被代理拦截,执行切面行为后再调用目标对象。
spring首先会判断目标对象是不是实现了接口,如果实现了接口,那么默认使用jdk动态代理机制来创建代理对象;否则则使用cglib来通过字节码生成来创建代理对象。当然用户也是可以指定的,动态代理通过反射调用性能上估计不如cglib。
7 aop的关键概念
- JoinPoint:代表程序运行时的一个具体的织入点,例如DefaultFooService
- Pointcut:一组JoinPoint的集合,通常由正则表达式来定义,如theExecutionOfSomeFooServiceMethod
- Advice:切面的逻辑,如SimpleProfiler
- Advisor:一个Advisor包含一个Advice和一个PointCut,相当于是个媒婆,把两者串起来。如<aop:around pointcut-ref="theExecutionOfSomeFooServiceMethod" method="profile"/>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- this is the object that will be proxied by Spring's AOP infrastructure --> <bean id="fooService" class="com.longji.aop.DefaultFooService"/> <!-- this is the actual advice itself --> <bean id="profiler" class="com.longji.aop.SimpleProfiler"/> <aop:config> <aop:aspect ref="profiler"> <aop:pointcut id="theExecutionOfSomeFooServiceMethod" expression="execution(* com.longji.aop.FooService.getFoo(String,int)) and args(name, age)"/> <aop:around pointcut-ref="theExecutionOfSomeFooServiceMethod" method="profile"/> </aop:aspect> </aop:config> </beans>
8 如何让这些 Bean 对象有一定的扩展性,就是可以加入用户的一些操作。对 Spring 的 Ioc 容器来说,主要有这么几个。BeanFactoryPostProcessor, BeanPostProcessor。他们分别是在构建 BeanFactory 和构建 Bean 对象时调用。还有就是 InitializingBean 和 DisposableBean 他们分别是在 Bean 实例创建和销毁时被调用。用户可以实现这些接口中定义的方法,Spring 就会在适当的时候调用他们。还有一个是 FactoryBean 他是个特殊的 Bean,这个 Bean 可以被用户更多的控制。
http://www.ibm.com/developerworks/cn/java/j-lo-spring-principle/index.html?ca=drs-
9 spring的ioc是基于反射的。虽然反射有性能损耗,但是spring ioc只在构建对象的时候,使用反射动态构建,对于对象的后续方法调用,和普通调用无异。所以一旦对象实例化结束,那么性能上面是不会有损耗的。特别是注入spring 容器的bean一般都是单例,很少会出现在运行时不断地用反射去构造一个对象的场景。
http://blog.csdn.net/it_man/article/details/4402245
10 普通bean和神奇的工厂bean,普通bean返回配置文件中类的实例,而工厂bean返回getObject的实例,具有更大的灵活性
spring的aop基于jdk动态代理,动态代理是很王道的特性。
参考http://hill007299.iteye.com/blog/1563554
http://www.khotyn.com/2010/08/02/spring_aop_overview/