Spring 实现原理
一、 Spring核心I/O以及AOP
1. Spring出现原因及目标
之前EJB的J2EE服务对代码有侵入性,使得开发与测试都比较困难;
而Spring则将J2EE的服务抽象出来,通过Ioc以及AOP来添加这些服务,一方面普通的业务POJO类更容易开发和测试,另一方面用则添加的模式也减少了框架复杂性;
2. Resource,ResourceLoader(BeanDefinitionReader),BeanDefinition,BeanDefinitionRegistry,BeanFactory,ApplicationContext,FactoryBean关系
1)通过Resource接口定位不同的资源文件,如classpath,file,url等;
2)通过ResourceLoader(BeanDefinitionReader)来加载,解析资源文件,从而产生Bean定义对象BeanDefinition;
3)向BenaFactory中注册BeanDefinition对象;
4)BeanFactory对象产生FactoryBean对象,并根据BeanDefinition的配置指导FactoryBean产生通用的Bean;
而ApplicationContext相当于Facade外观模式,整合常用的Resource,ResourceLoader,BeanFactory,BeanDefinition,同时会标识应用环境,捕获各种事件等;
3. Spring中获取对象工厂的方法:
1)初始化ApplicationContext对象
代码:
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
适用于独立的应用程序,而非B/S程序,因为其是一个独立的容器,得到的是一个新的对象,而B/S中通常需要的是应用程序中的相同对象;
2)通过Spring提供的工具类获取ApplicationContext对象
代码:
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ac1.getBean("beanId");
适用于Action层,因为其需要获取到ServletContext对象;
3)继承自抽象类ApplicationObjectSupport
抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。
Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。
4)继承自抽象类WebApplicationObjectSupport
类似上面方法,调用getWebApplicationContext()获取WebApplicationContext
5)实现接口ApplicationContextAware
实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。
Spring初始化时,会通过该方法将ApplicationContext对象注入。
4. AutoWire实现原理:
AutoWire只是一种简化,与其它方式相同,也是通过BeanDefinition和Class文件二者结合产生Bean;
首先,AutoWire与其它产生方式一样,必须有对应的BeanDefinition,故必须通过配置或者注解的方式使Spring找到相关的类;
AutoWire的几种值:
1)No:即不启用自动装配。Autowire默认的值。
2)byName:通过属性的名字的方式查找JavaBean依赖的对象并用set方法为其注入,如果另外添加有@AutoWire,则无须SET方法;
3)byType:通过属性的类型查找JavaBean依赖的对象并为其注入。
4)constructor:通byType一样,也是通过类型查找依赖对象。与byType的区别在于它不是使用Seter方法注入,而是使用构造子注入。
5)autodetect:在byType和constructor之间自动的选择注入方式。
5. @AutoWire VS @Resource
二者都是自动注入,区别在于一个默认按byType,一个默认采用byName;
可添加@Qualifier,来改变默认方式;
6. 注解与配置的比较
配置:
可灵活改变组件的依赖关系,而无须修改代码重新编译;
某些非自身开发的代码只能用配置的方式来做依赖初始化;
配置文件同时反映了Bean之间的关系,Bean方法之上的AOP等代理关系,故文件本身也相当于部分文档的作用;
在有大量Bean的项目中,配置文件本身会非常庞大,如果大部分Bean的关系是显而易见的,则会增加开发工作量以及埋没重要的配置内容;
注解:
配置文件会很小,减少了开发工作量,同时也使得重要的配置关系得以显现;
在约定优于配置的情况下,很多Bean之间的关系其实是明显的,无须使用配置文件来体现;
非自身开发的代码无法用注解的方式;
二、 Spring的AOP实现原理
1. 建立Advice通知对象,即实现各种AOP操作接口的对象;
2. 建立Pointcut切点对象,即方法匹配的配置,相当于target;
3. Advisor通知器对象则执有Advice和Pointcut对象;
4. ProxyFactoryBean通过getBean()先拿到原本的POJO对象;
5. 获取Advicor拦截器链,并对应的进行适配和注册
6. 通过JDK动态代理或者CGLIB的方式生成包含拦截链方法的代理类对象;
7. 执行时通过调用preceed()方法逐个运行拦截器的拦截方法,进而调用Advisor通知器的方法来执行AOP;
三、 Spring实现数据库操作组件
主要有三种方式:纯JDBC的JDBCTemplate,整合Hibernate,ibatis,都是通过模板类的方式使用;
三种方式的实现原理基本相同,即
1. 实现模板类JDBCTemplate,HibernateTemplate,SqlMapClientTemplate
2. 模板类中执有基本的相应对象,如connetion,session,sessionfactory等;
3. 模板类中对于连接建立,提交异常处理等通常都已实现;
四、 Spring实现事务处理
1. Connection,Session,Transaction;
在Spring中,无论JDBCTemplate还是Hibernate Session,其Connection都是通过TransactionSynchronizationManager得到的;
而Transaction则是通过统一的AOP模型,采用模型中的AbstractPlatformTransactionInterceptor来实现;
在真正的实现过程中,有AbstractPlatformTransactionManager模板类来实现对事物传播的各种实现,
而由DataSourceTransactionManager,JTATransactionManager,HibernateTransactionManager子类来实现不同的事务子操作;
如:新建,挂起,嵌套,回滚,提交等
Spring事务处理包括两部分,基本的JDBC事务属性和传播属性;
其中第一部分由所使用的TractionManager来实现,而传播属性则由Spring的AbstractPlatformTransactionManager来实现;
实现方式分成2种:一种编程式,一种声明式;
编程式即直接通过代码调用相关对象来实现事务,而声明式则是通过配置的方式来实现;
TractionManager有三种:DataSourceTransactionManager,JTATransactionManager,HibernateTransactionManager;
分别对应于Hibernate的事务管理,JDBC的事务管理,以及标准的JTA的事务管理;
2. Spring实现事务处理过程 (Connection,TransactionManager,TransactionAttribute,TransactionInterceptor,Advisor,TransactionInfo,TransactionStatus,AbstractPlatformTransactionInterceptor,SavePoint,TransactionSynchronizationManager,ConnectionHolder)
1)在配置文件中配置事务,其中包括事务管理器的JDBC事务的相关配置,以及事务传播的AOP配置;
2)通过TransactionInterceptor来读取事务配置属性;
3)通过TransactionAttribute来封装事务处理属性的读取,解析和配置;
4)通过AOP来实现在指定切面调用TransactionInterceptor来实现事务处理; 5)在对应的实现AOP方法中启用事务,获取TransactionInfo以及其子对象TransactionStatus,TransactionInfo包括了事务的配置信息以及TransactionStatus包含的当前事务的信息;
TransactionManager依据JDBC事务的相关配置来做事务的相关处理;
6)AbstractPlatformTransactionManager根据事务传播属性的配置以及当前事务状态信息,决定执行事务的新建,挂起,嵌套,异常,提交等操作;
而事务的挂起和嵌套,则依赖于具体的TransactionManager是否支持事务的相应操作,而TransactionManager则依赖与Conn是否支持SavePoint(JDBC3);
AbstractPlatformTransactionManager会根据TransactionStatus来决定事务管理器的各种操作;
(如方法结束时,根据是否是新事务来决定是否在当前方法中调用事务的Commit,
事务回滚时根据TransactionStatus以及传播属性决定是否roolback或者是否rollback到一个指定的SavePoint
事务新建时根据传播属性决定是否真的新建事务)
3. 事务管理器与Spring事务管理的关系
Spring事务管理由具体的事务管理器来实现,通过模板类AbstractPlatformTransactionInterceptor结合不同的子类
4. DataSourceTransactionManager与HibernateTransactionManager的区别:
DataSourceTransactionManager只管理JDBC事务,因为其代码中事务只有ConnectionHolder对象;
而HibernateTransactionManager则可以管理JDBC和session事务,因为其代码中事务持有ConnectionHolder和SessionHolder对象; HibernateTransactionManager能管理JDBCTemplate事务的原因在于HibernateTransactionManager与JDBCTemplate都通过TransactionSynchronizationManager来获取连接,而TransactionSynchronizationManager会先从线程中看当前线程是否已绑定connection,如果有则取当前Connection;故JDBCTemplate与session实际上取到的是同一个Connection,故可以进行JDBCTemplate与session事务的混合管理;
从这个角度看,如果想进行JDBC与session的混合管理,则不能自己建Connection,而要通过TransactionSynchronizationManager来取连接;
5. 与sessionFactory的整合CONNECTION
sessionFactory用的是spring执有的localsessionfactorybean类,该类执有Hibernate的SessionFactory对象;
而sessionFactory获取session的连接时,通过也是先从当前线程看是否有Connection,如有则从线程取;
通过该对象生成session时,提供的Connection参数依然是从当前事务或者TransactionSynchronizationManager得来;
6. 普通AOP与事务的Advisor实现
都是通过AOP的动态代理以及AOP拦截器来实现; 不同之处在于,一般的AOP都是无状态的方法,即方法的执行只依赖于传入的参数,而事务的传播属性则依赖于TransactionStatus这个本地线程变量来决定执行何种操作以及调用事务管理器的何种方法;
Spring的整体结构,初始化顺序以及执行顺序????????
aop,事务, datasource,配置,自动组装,sessiofactory,struts,资源文件,JNDI
一、 Spring核心I/O以及AOP
1. Spring出现原因及目标
之前EJB的J2EE服务对代码有侵入性,使得开发与测试都比较困难;
而Spring则将J2EE的服务抽象出来,通过Ioc以及AOP来添加这些服务,一方面普通的业务POJO类更容易开发和测试,另一方面用则添加的模式也减少了框架复杂性;
2. Resource,ResourceLoader(BeanDefinitionReader),BeanDefinition,BeanDefinitionRegistry,BeanFactory,ApplicationContext,FactoryBean关系
1)通过Resource接口定位不同的资源文件,如classpath,file,url等;
2)通过ResourceLoader(BeanDefinitionReader)来加载,解析资源文件,从而产生Bean定义对象BeanDefinition;
3)向BenaFactory中注册BeanDefinition对象;
4)BeanFactory对象产生FactoryBean对象,并根据BeanDefinition的配置指导FactoryBean产生通用的Bean;
而ApplicationContext相当于Facade外观模式,整合常用的Resource,ResourceLoader,BeanFactory,BeanDefinition,同时会标识应用环境,捕获各种事件等;
3. Spring中获取对象工厂的方法:
1)初始化ApplicationContext对象
代码:
ApplicationContext ac = new FileSystemXmlApplicationContext("applicationContext.xml");
ac.getBean("beanId");
适用于独立的应用程序,而非B/S程序,因为其是一个独立的容器,得到的是一个新的对象,而B/S中通常需要的是应用程序中的相同对象;
2)通过Spring提供的工具类获取ApplicationContext对象
代码:
ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);
ac1.getBean("beanId");
适用于Action层,因为其需要获取到ServletContext对象;
3)继承自抽象类ApplicationObjectSupport
抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。
Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。
4)继承自抽象类WebApplicationObjectSupport
类似上面方法,调用getWebApplicationContext()获取WebApplicationContext
5)实现接口ApplicationContextAware
实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。
Spring初始化时,会通过该方法将ApplicationContext对象注入。
4. AutoWire实现原理:
AutoWire只是一种简化,与其它方式相同,也是通过BeanDefinition和Class文件二者结合产生Bean;
首先,AutoWire与其它产生方式一样,必须有对应的BeanDefinition,故必须通过配置或者注解的方式使Spring找到相关的类;
AutoWire的几种值:
1)No:即不启用自动装配。Autowire默认的值。
2)byName:通过属性的名字的方式查找JavaBean依赖的对象并用set方法为其注入,如果另外添加有@AutoWire,则无须SET方法;
3)byType:通过属性的类型查找JavaBean依赖的对象并为其注入。
4)constructor:通byType一样,也是通过类型查找依赖对象。与byType的区别在于它不是使用Seter方法注入,而是使用构造子注入。
5)autodetect:在byType和constructor之间自动的选择注入方式。
5. @AutoWire VS @Resource
二者都是自动注入,区别在于一个默认按byType,一个默认采用byName;
可添加@Qualifier,来改变默认方式;
6. 注解与配置的比较
配置:
可灵活改变组件的依赖关系,而无须修改代码重新编译;
某些非自身开发的代码只能用配置的方式来做依赖初始化;
配置文件同时反映了Bean之间的关系,Bean方法之上的AOP等代理关系,故文件本身也相当于部分文档的作用;
在有大量Bean的项目中,配置文件本身会非常庞大,如果大部分Bean的关系是显而易见的,则会增加开发工作量以及埋没重要的配置内容;
注解:
配置文件会很小,减少了开发工作量,同时也使得重要的配置关系得以显现;
在约定优于配置的情况下,很多Bean之间的关系其实是明显的,无须使用配置文件来体现;
非自身开发的代码无法用注解的方式;
二、 Spring的AOP实现原理
1. 建立Advice通知对象,即实现各种AOP操作接口的对象;
2. 建立Pointcut切点对象,即方法匹配的配置,相当于target;
3. Advisor通知器对象则执有Advice和Pointcut对象;
4. ProxyFactoryBean通过getBean()先拿到原本的POJO对象;
5. 获取Advicor拦截器链,并对应的进行适配和注册
6. 通过JDK动态代理或者CGLIB的方式生成包含拦截链方法的代理类对象;
7. 执行时通过调用preceed()方法逐个运行拦截器的拦截方法,进而调用Advisor通知器的方法来执行AOP;
三、 Spring实现数据库操作组件
主要有三种方式:纯JDBC的JDBCTemplate,整合Hibernate,ibatis,都是通过模板类的方式使用;
三种方式的实现原理基本相同,即
1. 实现模板类JDBCTemplate,HibernateTemplate,SqlMapClientTemplate
2. 模板类中执有基本的相应对象,如connetion,session,sessionfactory等;
3. 模板类中对于连接建立,提交异常处理等通常都已实现;
四、 Spring实现事务处理
1. Connection,Session,Transaction;
在Spring中,无论JDBCTemplate还是Hibernate Session,其Connection都是通过TransactionSynchronizationManager得到的;
而Transaction则是通过统一的AOP模型,采用模型中的AbstractPlatformTransactionInterceptor来实现;
在真正的实现过程中,有AbstractPlatformTransactionManager模板类来实现对事物传播的各种实现,
而由DataSourceTransactionManager,JTATransactionManager,HibernateTransactionManager子类来实现不同的事务子操作;
如:新建,挂起,嵌套,回滚,提交等
Spring事务处理包括两部分,基本的JDBC事务属性和传播属性;
其中第一部分由所使用的TractionManager来实现,而传播属性则由Spring的AbstractPlatformTransactionManager来实现;
实现方式分成2种:一种编程式,一种声明式;
编程式即直接通过代码调用相关对象来实现事务,而声明式则是通过配置的方式来实现;
TractionManager有三种:DataSourceTransactionManager,JTATransactionManager,HibernateTransactionManager;
分别对应于Hibernate的事务管理,JDBC的事务管理,以及标准的JTA的事务管理;
2. Spring实现事务处理过程 (Connection,TransactionManager,TransactionAttribute,TransactionInterceptor,Advisor,TransactionInfo,TransactionStatus,AbstractPlatformTransactionInterceptor,SavePoint,TransactionSynchronizationManager,ConnectionHolder)
1)在配置文件中配置事务,其中包括事务管理器的JDBC事务的相关配置,以及事务传播的AOP配置;
2)通过TransactionInterceptor来读取事务配置属性;
3)通过TransactionAttribute来封装事务处理属性的读取,解析和配置;
4)通过AOP来实现在指定切面调用TransactionInterceptor来实现事务处理; 5)在对应的实现AOP方法中启用事务,获取TransactionInfo以及其子对象TransactionStatus,TransactionInfo包括了事务的配置信息以及TransactionStatus包含的当前事务的信息;
TransactionManager依据JDBC事务的相关配置来做事务的相关处理;
6)AbstractPlatformTransactionManager根据事务传播属性的配置以及当前事务状态信息,决定执行事务的新建,挂起,嵌套,异常,提交等操作;
而事务的挂起和嵌套,则依赖于具体的TransactionManager是否支持事务的相应操作,而TransactionManager则依赖与Conn是否支持SavePoint(JDBC3);
AbstractPlatformTransactionManager会根据TransactionStatus来决定事务管理器的各种操作;
(如方法结束时,根据是否是新事务来决定是否在当前方法中调用事务的Commit,
事务回滚时根据TransactionStatus以及传播属性决定是否roolback或者是否rollback到一个指定的SavePoint
事务新建时根据传播属性决定是否真的新建事务)
3. 事务管理器与Spring事务管理的关系
Spring事务管理由具体的事务管理器来实现,通过模板类AbstractPlatformTransactionInterceptor结合不同的子类
4. DataSourceTransactionManager与HibernateTransactionManager的区别:
DataSourceTransactionManager只管理JDBC事务,因为其代码中事务只有ConnectionHolder对象;
而HibernateTransactionManager则可以管理JDBC和session事务,因为其代码中事务持有ConnectionHolder和SessionHolder对象; HibernateTransactionManager能管理JDBCTemplate事务的原因在于HibernateTransactionManager与JDBCTemplate都通过TransactionSynchronizationManager来获取连接,而TransactionSynchronizationManager会先从线程中看当前线程是否已绑定connection,如果有则取当前Connection;故JDBCTemplate与session实际上取到的是同一个Connection,故可以进行JDBCTemplate与session事务的混合管理;
从这个角度看,如果想进行JDBC与session的混合管理,则不能自己建Connection,而要通过TransactionSynchronizationManager来取连接;
5. 与sessionFactory的整合CONNECTION
sessionFactory用的是spring执有的localsessionfactorybean类,该类执有Hibernate的SessionFactory对象;
而sessionFactory获取session的连接时,通过也是先从当前线程看是否有Connection,如有则从线程取;
通过该对象生成session时,提供的Connection参数依然是从当前事务或者TransactionSynchronizationManager得来;
6. 普通AOP与事务的Advisor实现
都是通过AOP的动态代理以及AOP拦截器来实现; 不同之处在于,一般的AOP都是无状态的方法,即方法的执行只依赖于传入的参数,而事务的传播属性则依赖于TransactionStatus这个本地线程变量来决定执行何种操作以及调用事务管理器的何种方法;
Spring的整体结构,初始化顺序以及执行顺序????????
aop,事务, datasource,配置,自动组装,sessiofactory,struts,资源文件,JNDI