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范围

上下文

回滚条件

异常

超时

Spring知识梳理的更多相关文章

  1. spring 知识梳理

    https://github.com/spring-projects/spring-framework  spring github地址

  2. spring远程服务知识梳理

    序:本文主要是总结和归纳spring的远程服务相关知识,可作为入门学习笔记.写博客目的也是为了进行知识梳理,便于以后查看.本文主要参考资料 spring 实战第三版 本文主要讨论内容如下: 远程调度概 ...

  3. MySQL 基础知识梳理

    MySQL 的安装方式有多种,但是对于不同场景,会有最适合该场景的 MySQL 安装方式,下面就介绍一下 MySQL 常见的安装方法,包括 rpm 安装,yum 安装,通用二进制安装以及源码编译安装, ...

  4. [SQL] SQL 基础知识梳理(一)- 数据库与 SQL

    SQL 基础知识梳理(一)- 数据库与 SQL [博主]反骨仔 [原文地址]http://www.cnblogs.com/liqingwen/p/5902856.html 目录 What's 数据库 ...

  5. [SQL] SQL 基础知识梳理(二) - 查询基础

    SQL 基础知识梳理(二) - 查询基础 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5904824.html 序 这是<SQL 基础知识梳理( ...

  6. [SQL] SQL 基础知识梳理(三) - 聚合和排序

    SQL 基础知识梳理(三) - 聚合和排序 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5926689.html 序 这是<SQL 基础知识梳理 ...

  7. [SQL] SQL 基础知识梳理(四) - 数据更新

    SQL 基础知识梳理(四) - 数据更新 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5929786.html 序 这是<SQL 基础知识梳理( ...

  8. [SQL] SQL 基础知识梳理(五) - 复杂查询

    SQL 基础知识梳理(五) - 复杂查询 [博主]反骨仔 [原文]http://www.cnblogs.com/liqingwen/p/5939796.html 序 这是<SQL 基础知识梳理( ...

  9. solr DIH 知识梳理

    solr DIH 知识梳理 web.xml中listener配置 <listener> <listener-class>org.apache.solr.handler.data ...

随机推荐

  1. python3字符编码错误

    在3.x 这里返回的是bytes-like类型, 所以这里不需要释放编码 ,释放也没有意义, 而是应该encode 转换成我们需要的编码, 之所会造成类型错误,原因是就在这里. 他们返回的类型不一样, ...

  2. Android訪问网络,使用HttpURLConnection还是HttpClient?

    原文地址:http://android-developers.blogspot.com/2011/09/androids-http-clients.html 大多数的Android应用程序都会使用HT ...

  3. JSTL函数标签

    tld 文件代码 <?xml version="1.0" encoding="UTF-8" ?> <taglib xmlns="ht ...

  4. UVA - 11077 Find the Permutations (置换)

    Sorting is one of the most usedoperations in real life, where Computer Science comes into act. It is ...

  5. POJ1179 Polygon 区间DP

    题目大意: 多边形游戏,有N个顶点的多边形,3 <= N <= 50 ,多边形有N条边,每个顶点中有一个数字(可正可负),每条边上或者是“+”号,或者是“*”号.边从1到N编号,首先选择一 ...

  6. [jzoj 6073] 河 解题报告 (DP)

    interlinkage: https://jzoj.net/senior/#main/show/6073 description: solution: 考虑一条河$x$被染的效果 显然对于一条河$i ...

  7. A - A Compatible Pair

    Problem description Nian is a monster which lives deep in the oceans. Once a year, it shows up on th ...

  8. Solr.NET快速入门(七)【覆盖默认映射器,NHibernate集成】

    覆盖默认映射器 默认情况下,SolrNet使用属性映射Solr字段. 但是,您可能需要使用另一个映射程序. 替换默认映射器取决于您如何设置库: 内置容器 如果使用默认的内置容器,可以在调用Startu ...

  9. Android 低功耗蓝牙的多设备连接与数据接收,简单实现

    在网络层,互联网提供所有应用程序都要使用的两种类型的服务,尽管目前理解这些服务的细节并不重要,但在所有TCP/IP概述中,都不能忽略他们: 无连接分组交付服务(Connectionless Packe ...

  10. hdu2680 Choose the best route 最短路(多源转单源)

    此题中起点有1000个,边有20000条.用链式前向星建图,再枚举起点用SPFA的话,超时了.(按理说,两千万的复杂度应该没超吧.不过一般说计算机计算速度 1~10 千万次/秒.也许拿最烂的计算机来卡 ...