1.Spring的 IOC和AOP机制 ?
Spring 是完全面向接口的设计,降低程序耦合性,主要是事务控制并创建bean实例对象。在ssh整合时,充当黏合剂的作用。IOC(Inversion of Control) 控制反转/依赖注入,又称DI(Dependency Injection) (依赖注入)和AOP(面向切面编程),这两个也是 Spring 的灵魂。
IOC的作用:产生对象实例,所以它是基于工厂设计模式的
1.1 什么是IOC?
控制反转,把创建对象的权利交给spring
1.2 Spring IOC的注入
IOC控制反转。它是一种思想而不是一种技术实现。
代理模式是常用的Java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
作用:Java开发领域对象的创建及管理的问题。
例如:现有类A依赖类B
- **传统的开发方式:**往往是在类A手动通过new关键字来new一个B对象出来
- **使用IOC思想的开发方式:**不通过new关键字来创建对象,而是通过IOC容器(spring框架)来帮助我们实例化对象。我们需要哪个对象,直接从IOC容器里面拿就行
通过属性进行注入,通过构造函数进行注入,
注入对象数组 注入List集合
注入Map集合 注入Properties类型
Spring的 IoC容器是 Spring的核心,Spring AOP是 Spring框架的重要组成部分。
1.3 Spring IOC 自动绑定模式:
可以设置autowire按以下方式进行绑定
按byType只要类型一致会自动寻找,
按byName自动按属性名称进行自动查找匹配.
总结:以上两种开发方式的对比来看:我们丧失一个权利(创建,管理对象的权利),从而等到一个好处(不用考虑对象的创建、管理的一系列的事情)
1.4 什么是DI
属性的依赖注入,spring在通过IOC创建对象的时候,如果对象还有属性,就一并给赋值进去DI是在IOC的基础上进行对象的属性注入
问:IOC和DI的区别?
IOC是一种设计思想或者说是一种某种模式。这个设计思想就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理,IOC在其他语言中也有应用,并非Spring特有**。IOC容器时Spring实现IOC的载体,IOC实际上就是一个Map(key,value),Map中存放的是各种对象**
IOC最常见以及最合理的实现方式叫依赖注入(简称DI)
1.5 IOC:控制反转:
IOC:控制反转:
在传统的程序设计中,当调用者需要被调用者的协助时,通常由调用者来创建被调用者的实例。但在 Spring里创建被调用者的工作不再由调用者来完成,因此控制反转(IOC);创建被调用者实例的工作通常由 Spring容器来完成,然后注入调用者,因此也被称为依赖注入(DI),依赖注入和控制反转是同一个概念。
面向切面编程(AOP)是以另一个角度来考虑程序结构,通过分析程序结构的关注点来完善面向对象编程(OOP)。OOP将应用程序分解成各个层次的对象,而AOP将程序分解成多个切面(切面就是要添加的非核心功能)。Spring AOP 只实现了方法级别的连接点,在J2EE应用中,AOP拦截到方法级别的操作就已经足够。在 Spring中,未来使 IoC方便地使用健壮、灵活的企业服务,需要利用 Spring AOP实现为IoC和企业服务之间建立联系。
IOC控制反转也叫依赖注入。利用了工厂模式将对象交给容器管理,你只需要在 Spring 总配置文件中配置相应的bean,以及设置相关的属性,让 Spring容器来生成类的实例对象以及管理对象。在 Spring容器启动的时候,Spring会把你在配置文件中配置的 bean都初始化好(这里就会涉及到复杂的 bean 创建的生命周期),然后在你需要调用的时候,就把它已经初始化好的那些 bean 分配给你需要调用这些 bean的类(假设这个类名是A),分配的方法就是调用 A 的 setter方法来注入,而不需要你在A里面 new 这些 bean了。
1.6 Spring实现IOC控制反转描述:
原来需要我们自己进行bean的创建以及注入,而现在交给spring容器去完成bean的创建以及注入。
所谓的“控制反转”就是 对象控制权的转移,从程序代码本身转移到了外部容器。
官方解释:
控制反转即IoC (Inversion of Control),
它把传统上由程序代码直接操控的对象的调用权交给容器,
通过容器来实现对象组件的装配和管理。
所谓的“控制反转”概念就是对组件对象控制权的转移,
从程序代码本身转移到了外部容器。
1.7 IOC解决了什么问题?(有什么好处?)
IOC的思想就是双方之间不相互依赖,由第三方容器来管理相关资源。
- 对象之间的耦合度或者说依赖程度降低
- 资源变的容易管理:比如你用Spring容器提供的话很容易就实现一个单例
例子:现有一个针对User的操作,利用Service和Dao两层结构进行开发
在没有使用IOC思想的情况下,Service层想要使用Dao层,需要通过new关键字在UserServiceImpl中手动new出IUserDao的具体实现类UserDaoImpl
开发过程中突然接到一个新的需求,针对对IUserDao 接口开发出另一个具体实现类。因为 Server 层依赖了IUserDao的具体实现,所以我们需要修改UserServiceImpl中 new 的对象。如果只有一个类引用了IUserDao的具体实现,可能觉得还好,修改起来也不是很费力气,但是如果有许许多多的地方都引用了IUserDao的具体实现的话,一旦需要更换IUserDao 的实现方式,那修改起来将会非常的头疼。
使用 IoC 的思想,我们将对象的控制权(创建、管理)交有 IoC 容器去管理,我们在使用的时候直接向 IoC 容器 “要” 就可以了
1.8 问:控制反转和依赖注入式同一个概念吗?
控制反转和依赖注入是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。
依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;
而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
问:bean 和 Java对象的区别:
① bean 是经历过完整的 bean 生命周期生成的放在单例池(singletonObjects)中的对象(大部分bean 是这样的)是有 Spring 容器创建出来的;
② bean 是一个Java对象,而Java对象并不一定是 bean(这一点并没有官方做支撑,个人理解)。
③ bean 创建好之后它的属性就是赋完值的,也就是 bean 是属性不是默认值的一个对象,而 new 出来的对象的属性是默认值。
2.AOP 面向方面(切面)编程
AOP是OOP的延续,是Aspect Oriented Programming的缩写,意思是面向方面(切面)编程。
AOP:面向切面编程(Aspect-Oriented Programming):
AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能、事务管理、权限认证、异常处理等等吧。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。
注:OOP(Object-Oriented Programming ) 面向对象编程
AOP 主要应用于日志记录,性能统计,安全控制,事务处理(项目中使用的)等方面。
2.1 Spring中实现AOP技术:
在Spring中可以通过代理模式来实现AOP代理模式分为:
- 静态代理:一个接口,分别有一个真实实现和一个代理实现。
- 动态代理:通过代理类的代理,接口和实现类之间可以不直接发生联系,而 可以在运行期(Runtime)实现动态关联。
动态代理有两种实现方式,可以通过jdk的动态代理实现也可以通过cglib来实现而AOP默认是通过jdk的动态代理来实现的。jdk的动态代理必须要有接口的支持,而cglib不需要,它是基于类的。
2.2 Spring AOP事务的描述:
在spring-common.xml里通过<aop:config>里面先设定一个表达式,设定对service里那些方法 如:对add* ,delete*,update*等开头的方法进行事务拦截。我们需要配置事务的传播(propagation="REQUIRED")特性,通常把增,删,改以外的操作需要配置成只读事务(read-only="true").只读事务可以提高性能。之后引入tx:advice,在tx:advice引用 transactionManager(事务管理),在事务管理里再引入sessionFactory,sessionFactory注入 dataSource,最后通过<aop:config> 引入txAdvice。
2.3 解释AOP
在软件业,AOP为Aspect Oriented Programming的缩写,意味:面向切面编程.通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术,AOP是OOP的延续.将一些共性的内容进行抽取,在需要用到的地方,以动态代理的方式进行插入.在不修 改源码的基础上,还能对源码进行前后增强。
例子:现有三个类,Horse、Pig、Dog,这三个类中都有 eat 和 run 两个方法。
通过 OOP 思想中的继承,我们可以提取出一个 Animal 的父类,然后将 eat 和 run 方法放入父类中,Horse、Pig、Dog通过继承Animal类即可自动获得 eat() 和 run() 方法。这样将会少些很多重复的代码。
OOP 编程思想可以解决大部分的代码重复问题。但是有一些问题是处理不了的。比如在父类 Animal 中的多个方法的相同位置出现了重复的代码,OOP 就解决不了。
依赖注入的方式有几种,各是什么?
- 构造器注入
将被依赖对象通过构造函数的参数注入给依赖对象,并且在初始化对象的时候注入。
优点:对象初始化完成后便可获得可使用的对象。
缺点:
① 当需要注入的对象很多时,构造器参数列表将会很长;
② 不够灵活。若有多种注入方式,每种方式只需注入指定几个依赖,那么就需要提供多个重载的构造函数,麻烦.
2.setter方法注入
IoC Service Provider 通过调用成员变量提供的setter函数将被依赖对象注入给依赖类。
优点:灵活。可以选择性地注入需要的对象。
缺点:依赖对象初始化完成后由于尚未注入被依赖对象,因此还不能使用。
3.接口注入
依赖类必须要实现指定的接口,然后实现该接口中的一个函数,该函数就是用于依赖注入。该函数的参数就是要注入的对象。
优点:接口注入中,接口的名字、函数的名字都不重要,只要保证函数的参数是要注入的对象类型即可。
缺点:侵入性太强,不建议使用。
2.4 什么是通知?有哪五种类型的通知?
通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过SpringAOP框架触发的代码段。Spring切面可以应用五种类型的通知:
- before:前置通知,在一个方法执行前被调用。
after: 在方法执行之后调用的通知,无论方法执行是否成功。
after-returning: 仅当方法成功完成后执行的通知。
after-throwing: 在方法抛出异常退出时执行的通知。
around: 在方法执行之前和之后调用的通知。
3.Spring框架
3.1 什么是spring框架?
spring是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的松耦合问题,是一个分层的javaEE一站式轻量级开源框架
3.2 spring的作用
方便解耦,简化开发,AOP编程支持,声明式事务支持,集成Junit更加方便的进行分层测试,方便集成各种优秀框架
3.3 解释Spring支持的几种bean的作用域
- singleton : bean在每个Spring ioc 容器中只有一个实例。
prototype:一个bean的定义可以有多个实例。
request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。
session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
缺省的Spring bean 的作用域是Singleton.
3.4 Spring支持的事务管理类型
编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。
3.5 你更倾向用那种事务管理类型?
大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。