Spring框架介绍

Spring是一个贯穿各层为javaEE提供一站式解决方案的框架,Spring中主要有容器模块,AOP模块,ORM和DAO模块,Web模块等等,具体有以下功能特征。

IOC(或者叫做DI)的核心机制,提供了bean工厂(Spring容器),提高了组件之间的解耦

AOP的将一些通用任务,如安全、事务、日志等集中进行管理,提高了复用性和管理的便捷性

ORM和DAO提供了与第三方持久层框架的良好整合,简化了底层数据访问

提供了优秀的Web MVC框架

ApplicationContext

Spring容器最基本的接口就是BeanFactory,BeanFactory负责配置,创建和管理Bean,这个接口提供getBean()方式直接获取通过容器创建的bean实例。

BeanFactory接口最常用的子接口是ApplicationContext接口,对于大部分J2EE,就是将ApplicationContext的实例作为容器。

ApplicationContext接口最常用的实现类是ClassPathXmlApplicationContext

当系统创建ApplicationContext容器时,默认会初始化所有的singleton Bean,包括调用构造函数创建Bean,并根据配置做依赖注入。因此在系统前期,创建ApplicationContext时将

有交大的系统开销,一旦ApplicationContext初始化完成,后面再获取singleton Bean的时候会得到较好的性能。

Spring国际化

Spring提供的ResourceBundleMessageSource Bean可以读取外部配置文件用来替换国际化代码标签.

Spring创建Bean的3种方式

1.ApplicationContext直接调用Bean的默认构造函数创建Bean实例

2.ApplicationContext调用用静态工厂方法,静态方法中创建Bean实例

3.ApplicationContext先实例化工厂,再创建Bean实例

工厂Bean: FactoryBean接口

  • 什么是工厂bean

Spring中的工厂Bean指的是一类特殊的Bean, 必须要实现FactoryBean接口(注意区分BeanFactory),用来生产特定产品。而传统/标准的工厂Bean是不需要实现这个接口的。

  • 工厂bean有什么特征

Spring框架中,如果一个普通bean实现了FactoryBean接口,这个Bean就成了一个Spring容器工厂Bean,调用这个工厂Bean的getBean()方法,实际上会执行FactoryBean接口的getObject()方法,

并且将getObject()方法的返回值作为getBean()的结果,而这里的getObject()是由开发者来实现的,开发者希望返回什么就返回什么。

  • Spring中有哪些工厂常见工厂Bean

PropertyPathFactoryBean , 用来返回ref指定bean的getter()方法的结果

MethodInvokingFactoryBean, 用来返回ref指定的bean,target指定的方法的结果

FieldRetrivingFactoryBean, 用来获取ref指定bean,target指定的字段值

Bean前行为和Bean后行为

对于单例(singleton)Spring可以精确控制生命周期,因此可以在bean的各个阶段指定各种行为。

在依赖关系注入之后,可以根据bena标签init-method让bena执行指定方法,也可以让bean实现InitialializingBean接口执行afterPropertiesSet()方法。

在bean被销毁之前,可以根据bean标签destory执行指定的方法,也可以让bean实现DisposableBean接口执行destroy()方法。

InitializingBean是针对单个Bean起作用的,Spring还提针对所有Bean的BeanPostProcessor接口,只要实现postProcessBeforeInitialization()和postProcessAfterInitialization(),就能对批量Bean在初始化前后插入特定方法。

同步singleton Bean和prototype Bean

如果在一个singleton类型的bean中注入一个prototype类型的bean时候,会发现有个问题,在整个应用程序生命周期,singleton bean只会被初始化一次,然而prototype bean每次都会重新创建并初始化,那么意味着singleton中的依赖注入并不是最新的。

解决办法就是将singleton类型的bean定义成抽象类,让Spring为其动态生成子类(反射),并重写getter()方法,在getter() 方法中调用 ctx.getBean("目标Bean")就能保证每次都是获取最新的prototype bean了。

Resource接口和ResourceLoader

Spring提供了一个Resource接口用来访问资源,其底层是封装了各种各种资源的访问方式,例如网络资源,本地资源,二进制数据等等,

通过Resource实现类的对象,可以对资源进行统一方式的操作,还可以通过Rescource实现类的对象获取资源的File实例,以java IO的方式操作资源。

Resource提供如下对资源的统一访问方法:getInputStream(), exists(), isOpen(), getDescription(), getFile(), getUrl()。

Spring为Resource默认已经实现了如下类:UrlResource, ClassPathResource, FileSystemResource, ServletContextResource, InputStreamResource, ByteArrayResource.

ResourceLoader接口的getResource(...)方法可以获取一个Resource的实例,而ApplicationContext也实现了ResourceLoader接口,

因此可以直接使用ctx.getResource(...)获取一个Resource实例,ApplicationContext会作为一个观察者,根据ApplicationContext的实现类型来决定选择Resource的哪个实现类,开发人员只需要面向接口编程,这是典型的观察者模式。

 ApplicationContext ctx = new ClassPathXmlApplicationContext("beans2.xml");
//ApplicationContext ctx = new FileSystemXmlApplicationContext("beans2.xml");
Resource res =ctx.getResource("beans2.xml");

上面是Spring的观察者模式获取Resource的代码,只需要面向接口编程,根据第1行和第2行选择的不同的ApplicationContext实现类,第3行就会获取对应的Resource实现类,这底层都由Spring处理了。

比ResourceLoader更能解耦的方式是直接将Resource的实例作为Bean的属性,这样就能直接在XML文件中配置需要访问的资源名称。

Spring AOP

Sping AOP默认使用Java JDK动态代理来创建AOP代理,因为Spring推荐的是面向接口的编程。当然也可以强制使用cglib进行动态代理。

Aspect是在类加载器层面进行编译增强,从而实现AOP,需要用特定的编译方法。Spring AOP可以使用根AspectJ一样的注解语法,但是底层依然使用Spring AOP实现的,不依赖于Aspect的编译器或者织入器。

常用增强处理有Beore,AfterRunning,AfterThrowing,After,Around等。

AfterRunning可以为Advice(增强方法)设置的形参指定一个数据类型,这个切面类只会匹配与形惨类型相同的返回值的方法。

AfterThrowing则可以为Advice(增强方法)设置的形参指定一个数据类型,这个切面类需要匹配抛出与形参类型相同的异常的方法。

After与Afterreturning的区别,Afterreturning只有在目标方法成功完成之后才会被织入,但是After无论目标方法正常结束还是遇到异常,都能织入增强处理。After就相当于finally{}代码块。

Around增强处理类似于Before增强和AfterReturning增强处理的总和,但是更强大。Around增强处理不仅可以随意控制目标方法的执行时机,还能修改方法的参数和返回值。

JoinPoint类的实例可以作为Before, Around, AfterReturning, After增强的Advice方法的参数,用来访问目标方法的参数

Spring缓存

Spring缓存底层也是需要借助第三方缓存工具来实现,例如EhCache(Hibernate缓存工具),上层则以统一API编程。

对于某些第三方缓存框架,还需要额外配置文件,例如EnCache,可以在 encache.xml中,为Spring的每一个Bean都配置一个缓存区。

基于类的缓存,将会缓存类中的所有方法,缓存之后,再次调用该方法,甚至调用名称不同但参数相同的方法,Spring都会返回缓存中以方法参数为Key的结果,而不是真正去执行这个方法。

使用@CacheEvict可以清除部分或者全部缓存

Spring事务

Sring没有提供任何事务支持,它只是负责包装底层的事务,可能是JDBC事务,可能是Hibernate事务,也可能是JTA事务,而在Spring层面,对外提供统一的编程API。

Spring事务的核心是PlatformTransactionManager接口,通过策略模式,ApplicationContext可以为其指定具体的实现类。开发人员只需要使用通用的getTransaction(); commint(); rollback();接口方法即可。

  • 编程式事务

就是直接在代码中使用PlatormTransactionManager提供的三个抽象方法进行事务流程控制。

  • 声明式事务

这种方式不需要讲事务控制流程写入代码中,而是通过AOP的方式,完全由配置文件完成事务的织入。这种方式是最好的,源码侵入性最低。

  • Spring事务对于传统事务面临问题的解决

PlatformTransactionManager接口的getTransaction()可以返回一个已经存在或者一个新的事务对象,该方法接受一个参数TransactionDefinition definiton,

TransactionDefinition接口中定义了事务的各种属性(隔离级别,传播行为,超时和是只读),具体实现则由具体类型的事务实现类去实现。

定义这些事务属性

事务隔离,具体含义参考JDBC事务的事务隔离

事务隔离是为了解决多个事务共享数据造成的各种冲突问题的,

ISOLATION_DEFAULT
ISOLATION_READ_UNCOMMITTED
ISOLATION_READ_COMMITTED
ISOLATION_REPEATABLE_READ
ISOLATION_SERIALIZABLE

传播行为

传播性是为了解决传统事务的“上下文相关”session中的上下文的界定的,例如对于事务嵌套,以前没有Spring帮助我们完成事务的时候我们必须自己手动的控制事务,例如当我们项目中仅仅使用hibernate,而没有集成进spring的时候,我们在一个service层中调用其他的业务逻辑方法,为了保证事物必须也要把当前的hibernate session传递到下一个方法中,或者采用ThreadLocal的方法,将session传递给下一个方法,其实都是一个目的。现在这个工作由spring来帮助我们完成

PROPAGATION_REQUIRED--支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。

PROPAGATION_SUPPORTS--支持当前事务,如果当前没有事务,就以非事务方式执行。

PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。

PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。

PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

事务范围

session范围

上下文

回滚条件

异常

超时

最新文章

  1. Failure to find xxx in xxx was cached in the local repository, resolution will not be reattempted until the update interval of nexus has elapsed or updates are forced @ xxx
  2. jquery插件图片延时加载实例详解
  3. [tem]树状数组
  4. 高性能MySQL笔记 第4章 Schema与数据类型优化
  5. jar-下载站点
  6. Error 0x800704cf
  7. linux全部命令
  8. IOS中怎么使用微软雅黑字体
  9. linux下mysql开启慢查询
  10. 正则化方法 exec 和match以及test
  11. [翻译]AOP编程
  12. Linux系统编程(30)—— socket编程之TCP/IP协议
  13. HDU 5815 - Golden Week
  14. PHP扩展开发-简单类扩展
  15. 《Java程序设计》第5周学习总结
  16. IntelliJ IDEA 2018 设置代码超出限制自动换行(最新版)
  17. javascript模板引擎template.js使用
  18. 格式时间转UTC时间
  19. Android与H5交互 原理与对比
  20. Linux vim快捷键

热门文章

  1. pl/sql developer 自动输入替换 光标自动定位
  2. CSS3 timing-function: steps()介绍
  3. POJ3126——Prime Path
  4. BAT常问问题总结以及回答(数据库篇)
  5. oc09--NSString
  6. oc3--类方法1
  7. Windows 10 MBR转GPT分区
  8. Reset and Clear Recent Items and Frequent Places in Windows 10
  9. 第20章 Redis配置
  10. JavaScript命名空间的理解与实现