Spring理论篇
1、Spring简介(百度百科):
1、Spr ing简介(百度百科):
要谈Spring的历史,就要先谈J2EE。J2EE应⽤程序的⼴泛实现是在1999年和2000年开始的,它的出现带来了诸如事务管理之类的核⼼中间层概念的标准化,但是在实践中并没有获得绝对的成功,因为开发效率,开发难度和实际的性能都令⼈失望。
曾经使⽤过EJB开发JAVA EE应⽤的⼈,⼀定知道,在EJB开始的学习和应⽤⾮常的艰苦,很多东西都不能⼀下⼦就很容易的理解。EJB要严格地实现各种不同类型的接⼝,类似的或者重复的代码⼤量存在。⽽配置也是复杂和单调,同样使⽤JNDI进⾏对象查的代码也是单调⽽枯燥。虽然有⼀些开发⼯作随着xdoclet的出现,⽽有所缓解,但是学习EJB的⾼昂代价,和极低的开发效率,极⾼的资源消耗,都造成了EJB的使⽤困难。⽽Spring出现的初衷就是为了解决类似的这些问题。
Spring的⼀个最⼤的⽬的就是使JAVA EE开发更加容易。同时,Spring之所以与Struts、Hibernate等单层框架不同,是因为Spring致⼒于提供⼀个以统⼀的、⾼效的⽅式构造整个应⽤,并且可以将单层框架以最佳的组合揉和在⼀起建⽴⼀个连贯的体系。可以说Spring是⼀个提供了更完善开发环境的⼀个框架,可以为POJO(Plain Ordinary Java Object)对象提供企业级的服务。
Spring的形成,最初来⾃Rod Jahnson所著的⼀本很有影响⼒的书籍《Expert One-on-One J2EE Design and Development》,就是在这本书中第⼀次出现了Spring的⼀些核⼼思想,该书出版于2002年。另外⼀本书《Expert One-on-One J2EE Development without EJB》,更进⼀步阐述了在不使⽤EJB开发JAVA EE企业级应⽤的⼀些设计思想和具体的做法。有时间了可以详细的研读⼀下。
Spring的初衷:
1、JAVA EE开发应该更加简单。
2、使⽤接⼝⽽不是使⽤类,是更好的编程习惯。Spring将使⽤接⼝的复杂度⼏乎降低到了零。
3、为JavaBean提供了⼀个更好的应⽤配置框架。
4、更多地强调⾯向对象的设计,⽽不是现⾏的技术如JAVA EE。
5、尽量减少不必要的异常捕捉。
6、使应⽤程序更加容易测试。
Spring的⽬标:
1、可以令⼈⽅便愉快的使⽤Spring。
2、应⽤程序代码并不依赖于Spring APIs。
3、Spring不和现有的解决⽅案竞争,⽽是致⼒于将它们融合在⼀起。
Spring的基本组成:
1、最完善的轻量级核⼼框架。
2、通⽤的事务管理抽象层。
3、JDBC抽象层。
4、集成了Toplink, Hibernate, JDO, and iBATIS SQL Maps。
5、AOP功能。
6、灵活的MVC Web应⽤框架。
2、IOC(控制反转)
(1)控制反转,指创建对象的控制权的转移,以前创建对象的主动权和时机是由⾃⼰把控的,⽽现在这种权⼒转移到Spring容器中,并由容器根据配置⽂件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散耦合,也利于功能的复⽤。DI依赖注⼊,和控制反转是同⼀个概念的不同⾓度的描述,即 应⽤程序在运⾏时依赖IoC容器来动态注⼊对象需要的外部资源。
(2)最直观的表达就是,IOC让对象的创建不⽤去new了,可以由spring⾃动⽣产,使⽤java的反射机制,根据配置⽂件在运⾏时动态的去创建对象以及管理对象,并调⽤对象的⽅法的。
(3)Spring的IOC有三种注⼊⽅式 :构造器注⼊、setter⽅法注⼊、根据注解注⼊。
3、AOP(⾯向切⾯)
作为⾯向对象的⼀种补充,⽤于将那些与业务⽆关,但却对多个对象产⽣影响的公共⾏为和逻辑,抽取并封装为⼀个可重⽤的模块,这个模块被命名为“切⾯”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提⾼了系统的可维护性。可⽤于权限认证、⽇志、事务处理。
AOP实现的关键在于 代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。
(1)AspectJ是静态代理的增强,所谓静态代理,就是AOP框架会在编译阶段⽣成AOP代理类,因此
也称为编译时增强,他会在编译阶段将AspectJ(切⾯)织⼊到Java字节码中,运⾏的时候就是增强之后的AOP对象。
(2)Spring AOP使⽤的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,⽽是每次运⾏时在内存中临时为⽅法⽣成⼀个AOP对象,这个AOP对象包含了⽬标对象的全部⽅法,并且在特定的切点做了增强处理,并回调原对象的⽅法。
Spring AOP中的动态代理主要有两种⽅式,JDK动态代理和CGLIB动态代理:
①JDK动态代理只提供接⼝的代理,不⽀持类的代理。核⼼InvocationHandler接⼝和Proxy类,InvocationHandler 通过invoke()⽅法反射来调⽤⽬标类中的代码,动态地将横切逻辑和业务编织在⼀起;接着,Proxy利⽤ InvocationHandler动态创建⼀个符合某⼀接⼝的的实例, ⽣成⽬标类的代理对象。
②如果代理类没有实现 InvocationHandler 接⼝,那么Spring AOP会选择使⽤CGLIB来动态代理⽬标类。CGLIB(Code Generation Library),是⼀个代码⽣成的类库,可以在运⾏时动态的⽣成指定类的⼀个⼦类对象,并覆盖其中特定⽅法并添加增强代码,从⽽实现AOP。CGLIB是通过继承的⽅式做的动态代理,因此如果某个类被标记为final,那么它是⽆法使⽤CGLIB做动态代理的。
(3)静态代理与动态代理区别在于⽣成AOP代理对象的时机不同,相对来说AspectJ的静态代理⽅式具有更好的性能,但是AspectJ需要特定的编译器进⾏处理,⽽Spring AOP则⽆需特定的编译器处理。
4、Spring框架中的单例Bea ns是线程安全的么?
4、Spr ing框架中的单例Bea
Spring框架并没有对单例bean进⾏任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者⾃⾏去搞定。但实际上,⼤部分的Spring bean并没有可变的状态(⽐如Serview类和DAO类),所以在某种程度上说Spring的单例bean是线程安全的。如果你的bean有多种状态的话(⽐如 View Model 对象),就需要⾃⾏保证线程安全。最浅显的解决办法就是将多态bean的作⽤域由“singleton”变更
为“prototype”。
Spring如何处理线程并发问题?
5、Spr ing如何处理线程并发问题?
在⼀般情况下,只有⽆状态的Bean才可以在多线程环境下共享,在Spring中,绝⼤部分Bean都可以声明为singleton作⽤域,因为Spring 对⼀些Bean中⾮线程安全状态采⽤ThreadLocal进⾏处理,解决线程安全问题。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采⽤了“时间换空间”的⽅式,仅提供⼀份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。⽽ThreadLocal采⽤了“空间换时间”的⽅式。
ThreadLocal会为每⼀个线程提供⼀个独⽴的变量副本,从⽽隔离了多个线程对数据的访问冲突。因为每⼀个线程都拥有⾃⼰的变量副本,
从⽽也就没有必要对该变量进⾏同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
Spring事务的实现⽅式和实现原理
6、Spr ing事务的实现⽅式和实现原理
Spring事务的本质其实就是数据库对事务的⽀持,没有数据库的事务⽀持,spring是⽆法提供事务功能的。真正的数据库层的事务提交和回滚是通过binlog或者redo log实现的。
(1)Spring事务的种类:
spring⽀持编程式事务管理和声明式事务管理两种⽅式:
①编程式事务管理使⽤TransactionTemplate。
②声明式事务管理建⽴在AOP之上的。其本质是通过AOP功能,对⽅法前后进⾏拦截,将事务处理的功能编织到拦截的⽅法中,也就是在⽬标⽅法开始之前加⼊⼀个事务,在执⾏完⽬标⽅法之后根据执⾏情况提交或者回滚事务。
声明式事务最⼤的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置⽂件中做相关的事务规则声明或通过@Transactional注解的⽅式,便可以将事务规则应⽤到业务逻辑中。
声明式事务管理要优于编程式事务管理,这正是spring倡导的⾮侵⼊式的开发⽅式,使业务代码不受污染,只要加上注解就可以获得完全的事务⽀持。唯⼀不⾜地⽅是,最细粒度只能作⽤到⽅法级别,⽆法做到像编程式事务那样可以作⽤到代码块级别。
(2)Spring的事务传播⾏为:
spring事务的传播⾏为说的是,当多个事务同时存在的时候,spring如何处理这些事务的⾏为。
① PROPAGATION_REQUIRED:如果当前没有事务,就创建⼀个新事务,如果当前存在事务,就加⼊该事务,该设置是最常⽤的设置。
② PROPAGATION_SUPPORTS:⽀持当前事务,如果当前存在事务,就加⼊该事务,如果当前不存在事务,就以⾮事务执⾏。‘
③ PROPAGATION_MANDATORY:⽀持当前事务,如果当前存在事务,就加⼊该事务,如果当前不存在事务,就抛出异常。
④ PROPAGATION_REQUIRES_NEW:创建新事务,⽆论当前存不存在事务,都创建新事务。
⑤ PROPAGATION_NOT_SUPPORTED:以⾮事务⽅式执⾏操作,如果当前存在事务,就把当前事务挂起。
⑥ PROPAGATION_NEVER:以⾮事务⽅式执⾏,如果当前存在事务,则抛出异常。
⑦ PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执⾏。如果当前没有事务,则按REQUIRED属性执⾏。
(3)Spring中的隔离级别:
① ISOLATION_DEFAULT:这是个 PlatfromTransactionManager 默认的隔离级别,使⽤数据库默认的事务隔离级别。
② ISOLATION_READ_UNCOMMITTED:读未提交,允许另外⼀个事务可以看到这个事务未提交的数据。
③ ISOLATION_READ_COMMITTED:读已提交,保证⼀个事务修改的数据提交后才能被另⼀事务读取,⽽且能看到该事务对已有记录的更新。
④ ISOLATION_REPEATABLE_READ:可重复读,保证⼀个事务修改的数据提交后才能被另⼀事务读取,但是不能看到该事务对已有记录的更新。
⑤ ISOLATION_SERIALIZABLE:⼀个事务在执⾏的过程中完全看不到其他事务对数据库所做的更新。
7、Spring AOP⾥⾯的常见的名词
7、Spr ing AOP⾥⾯的常见的名词
(1)切⾯(Aspect):被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切⾯可以使⽤通⽤类(基于模式的风格) 或者在普通类中以 @AspectJ 注解来实现。spring ioc注解
(2)连接点(Join point):指⽅法,在Spring AOP中,⼀个连接点 总是 代表⼀个⽅法的执⾏。
(3)通知(Advice):在切⾯的某个特定的连接点(Join point)上执⾏的动作。通知有各种类型,其中包括“around”、
“before”和“after”等通知。许多AOP框架,包括Spring,都是以做通知模型, 并维护⼀个以连接点为中⼼的链。
(4)切⼊点(Pointcut):切⼊点是指 我们要对哪些Join point进⾏拦截的定义。通过切⼊点表达式,指定拦截的⽅法,⽐如指定拦截add*、search*。
(5)引⼊(Introduction):(也被称为内部类型声明(inter-type declaration))。声明额外的⽅法或者某个类型的字段。Spring允许引⼊新的接⼝(以及⼀个对应的实现)到任何被代理的对象。例如,你可以使⽤⼀个引⼊来使bean实现 IsModified 接⼝,以便简化缓存机制。
(6)⽬标对象(Target Object): 被⼀个或者多个切⾯(aspect)所通知(advise)的对象。也有⼈把它叫做 被通知(adviced) 对象。 既然Spring AOP是通过运⾏时代理实现的,这个对象永远是⼀个 被代理(proxied) 对象。
(7)织⼊(Weaving):指把增强应⽤到⽬标对象来创建新的代理对象的过程。Spring是在运⾏时完
成织⼊。
切⼊点(pointcut)和连接点(join point)匹配的概念是AOP的关键,这使得AOP不同于其它仅仅提供拦截功能的旧技术。 切⼊点使得定位通知(advice)可独⽴于OO层次。 例如,⼀个提供声明式事务管理的around通知可以被应⽤到⼀组横跨多个对象中的⽅法上(例如服务层的所有业务操作)。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。