您的位置:首页 > 编程语言 > Java开发

spring基础知识汇总及常见面试题目总结

2016-05-13 09:37 731 查看
http://blog.csdn.net/u014744118/article/details/51367849

目录(?)[-]

Spring简介
Spring的核心机制

管理Bean
Eclipse使用Spring
依赖注入

理解依赖注入
设值注入
构造注入
两种注入方式的对比

Spring容器中的Bean

容器中Bean的作用域

使用自动装配注入合作者Bean

创建Bean的3种方式

使用构造器创建Bean实例
使用静态工厂方法创建Bean
调用实例工厂方法创建Bean

协调作用域不同步的Bean
两种后处理器

Bean后处理器
容器后处理器

Spring的零配置支持

搜索Bean类
使用Resource配置依赖
使用PostConstruct和PreDestroy定制生命周期行为
Spring40增强的自动装配和精确装配

Spring的AOP

为什么需要AOP
使用AspectJ实现AOP
AOP的基本概念
Spring的AOP支持


Spring简介

spring框架由Rod Johnson开发,2004年发布了Spring框架的第一版。Spring是一个从实际开发中抽取出来的框架,因此它完成了大量开发中的通用步骤,留给开发者的仅仅是与特定应用相关的部分,从而大大提高了企业应用的开发效率。

Spring总结起来优点如下:

低侵入式设计,代码的污染极低。

独立于各种应用服务器,基于Spring框架的应用,可以真正实现Write Once,Run Anywhere的承诺。

Spring的IoC容器降低了业务对象替换的复杂性,提高了组件之间的解耦。

Spring的AOP支持允许将一些通用任务如安全、事务、日志等进行集中式管理,从而提供了更好的复用。

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

Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可自由选用Spring框架的部分或全部。

Spring框架的组成结构图如下所示:




Spring的核心机制


管理Bean

程序主要是通过Spring容器来访问容器中的Bean,ApplicationContext是Spring容器最常用的接口,该接口有如下两个实现类:

ClassPathXmlApplicationContext: 从类加载路径下搜索配置文件,并根据配置文件来创建Spring容器。

FileSystemXmlApplicationContext: 从文件系统的相对路径或绝对路径下去搜索配置文件,并根据配置文件来创建Spring容器。

<span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">public</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">class</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">BeanTest</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">{</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">public</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">static</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">void</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> main</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">String</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> args</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">[])</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">throws</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">Exception</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">{</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">ApplicationContext</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> ctx </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">new</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">ClassPathXmlApplicationContext</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"beans.xml"</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">);</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">Person</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> p </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> ctx</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">.</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">getBean</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"person"</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">,</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">Person</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">.</span><span class="kwd" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">class</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">);</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
p</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">.</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">say</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">();</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">}</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">}</span>


Eclipse使用Spring

在Eclipse等IDE工具中,用户可以自建
User Library
,然后把Spring的Jar包都放入其中,当然也可以将Jar包直接放在项目的
/WEB-INF/lib
目录下,但是如果使用
User
Library
,在项目发布时,需要将用户库所引用的Jar文件随应用一起发布,就是将User Library所使用的Jar复制到
/WEB-INF/lib
目录下,这是因为对于一个Web应用,Eclipse部署Web应用时不会将用户库的Jar文件复制到
/WEB-INF/lib
下,需要手动复制。


依赖注入

Spring框架的核心功能有两个:

Spring容器作为超级大工厂,负责创建、管理所有的Java对象,这些Java对象被称为Bean。

Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为"依赖注入"的方式来管理Bean之间的依赖关系。

使用依赖注入,不仅可以为Bean注入普通的属性值,还可以注入其他Bean的引用。依赖注入是一种优秀的解耦方式,其可以让Bean以配置文件组织在一起,而不是以硬编码的方式耦合在一起。


理解依赖注入

Rod Johnson是第一个高度重视以配置文件来管理Java实例的协作关系的人,他给这种方式起了一个名字:控制反转(Inverse of Control,IoC)。后来Martine
Fowler为这种方式起了另一个名称:依赖注入(Dependency Injection),因此不管是依赖注入,还是控制反转,其含义完全相同。当某个Java对象(调用者)需要调用另一个Java对象(被依赖对象)的方法时,在传统模式下通常有两种做法:

原始做法: 调用者主动创建被依赖对象,然后再调用被依赖对象的方法。

简单工厂模式: 调用者先找到被依赖对象的工厂,然后主动通过工厂去获取被依赖对象,最后再调用被依赖对象的方法。

注意上面的主动二字,这必然会导致调用者与被依赖对象实现类的硬编码耦合,非常不利于项目升级的维护。使用Spring框架之后,调用者无需主动获取被依赖对象,调用者只要被动接受Spring容器为调用者的成员变量赋值即可,由此可见,使用Spring后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受——所以Rod
Johnson称之为控制反转。

另外从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量——相当于为调用者注入它依赖的实例,因此Martine Fowler称之为依赖注入。


设值注入

设值注入是指IoC容器通过成员变量的setter方法来注入被依赖对象。这种注入方式简单、直观,因而在Spring的依赖注入里大量使用。


构造注入

利用构造器来设置依赖关系的方式,被称为构造注入。通俗来说,就是驱动Spring在底层以反射方式执行带指定参数的构造器,当执行带参数的构造器时,就可利用构造器参数对成员变量执行初始化——这就是构造注入的本质。


两种注入方式的对比

设值注入有如下优点:

与传统的JavaBean的写法更相似,程序开发人员更容易理解、接受。通过setter方法设定依赖关系显得更加直观、自然。

对于复杂的依赖关系,如果采用构造注入,会导致构造器过于臃肿,难以阅读。Spring在创建Bean实例时,需要同时实例化其依赖的全部实例,因而导致性能下降。而使用设值注入,则能避免这些问题。

尤其在某些成员变量可选的情况下,多参数的构造器更加笨重。

构造注入优势如下:

构造注入可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。

对于依赖关系无需变化的Bean,构造注入更有用处。因为没有setter方法,所有的依赖关系全部在构造器内设定,无须担心后续的代码对依赖关系产生破坏。

依赖关系只能在构造器中设定,则只有组件的创建者才能改变组件的依赖关系,对组件的调用者而言,组件内部的依赖关系完全透明,更符合高内聚的原则。

注意:

建议采用设值注入为主,构造注入为辅的注入策略。对于依赖关系无须变化的注入,尽量采用构造注入;而其他依赖关系的注入,则考虑采用设值注入。


Spring容器中的Bean

对于开发者来说,开发者使用Spring框架主要是做两件事:①开发Bean;②配置Bean。对于Spring框架来说,它要做的就是根据配置文件来创建Bean实例,并调用Bean实例的方法完成"依赖注入"——这就是所谓IoC的本质。


容器中Bean的作用域

当通过Spring容器创建一个Bean实例时,不仅可以完成Bean实例的实例化,还可以为Bean指定特定的作用域。Spring支持如下五种作用域:

singleton: 单例模式,在整个Spring IoC容器中,singleton作用域的Bean将只生成一个实例。

prototype: 每次通过容器的getBean()方法获取prototype作用域的Bean时,都将产生一个新的Bean实例。

request: 对于一次HTTP请求,request作用域的Bean将只生成一个实例,这意味着,在同一次HTTP请求内,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用Spring时,该作用域才真正有效。

对于一次HTTP会话,session作用域的Bean将只生成一个实例,这意味着,在同一次HTTP会话内,程序每次请求该Bean,得到的总是同一个实例。只有在Web应用中使用Spring时,该作用域才真正有效。

global session: 每个全局的HTTP Session对应一个Bean实例。在典型的情况下,仅在使用portlet context的时候有效,同样只在Web应用中有效。

如果不指定Bean的作用域,Spring默认使用singleton作用域。prototype作用域的Bean的创建、销毁代价比较大。而singleton作用域的Bean实例一旦创建成果,就可以重复使用。因此,应该尽量避免将Bean设置成prototype作用域。


使用自动装配注入合作者Bean

Spring能自动装配Bean与Bean之间的依赖关系,即无须使用ref显式指定依赖Bean,而是由Spring容器检查XML配置文件内容,根据某种规则,为调用者Bean注入被依赖的Bean。

Spring自动装配可通过
<beans/>
元素的
default-autowire
属性指定,该属性对配置文件中所有的Bean起作用;也可通过对
<bean/>
元素的
autowire
属性指定,该属性只对该Bean起作用。

autowire
default-autowire
可以接受如下值:

no
: 不使用自动装配。Bean依赖必须通过ref元素定义。这是默认配置,在较大的部署环境中不鼓励改变这个配置,显式配置合作者能够得到更清晰的依赖关系。

byName
: 根据setter方法名进行自动装配。Spring容器查找容器中全部Bean,找出其id与setter方法名去掉set前缀,并小写首字母后同名的Bean来完成注入。如果没有找到匹配的Bean实例,则Spring不会进行任何注入。

byType
: 根据setter方法的形参类型来自动装配。Spring容器查找容器中的全部Bean,如果正好有一个Bean类型与setter方法的形参类型匹配,就自动注入这个Bean;如果找到多个这样的Bean,就抛出一个异常;如果没有找到这样的Bean,则什么都不会发生,setter方法不会被调用。

constructor
: 与byType类似,区别是用于自动匹配构造器的参数。如果容器不能恰好找到一个与构造器参数类型匹配的Bean,则会抛出一个异常。

autodetect
: Spring容器根据Bean内部结构,自行决定使用constructor或byType策略。如果找到一个默认的构造函数,那么就会应用byType策略。

当一个Bean既使用自动装配依赖,又使用ref显式指定依赖时,则显式指定的依赖覆盖自动装配依赖;对于大型的应用,不鼓励使用自动装配。虽然使用自动装配可减少配置文件的工作量,但大大将死了依赖关系的清晰性和透明性。依赖关系的装配依赖于源文件的属性名和属性类型,导致Bean与Bean之间的耦合降低到代码层次,不利于高层次解耦。
<span class="com" style="border: 0px; margin: 0px; padding: 0px; color: rgb(136, 0, 0);"><!--通过设置可以将Bean排除在自动装配之外--></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"><bean</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">id</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">""</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">autowire-candidate</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"false"</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">/></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">

</span><span class="com" style="border: 0px; margin: 0px; padding: 0px; color: rgb(136, 0, 0);"><!--除此之外,还可以在beans元素中指定,支持模式字符串,如下所有以abc结尾的Bean都被排除在自动装配之外--></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"><beans</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">default-autowire-candidates</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"*abc"</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">/></span>


创建Bean的3种方式


使用构造器创建Bean实例

使用构造器来创建Bean实例是最常见的情况,如果不采用构造注入,Spring底层会调用Bean类的无参数构造器来创建实例,因此要求该Bean类提供无参数的构造器。

采用默认的构造器创建Bean实例,Spring对Bean实例的所有属性执行默认初始化,即所有的基本类型的值初始化为0或false;所有的引用类型的值初始化为null。


使用静态工厂方法创建Bean

使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性并不是指定Bean实例的实现类,而是静态工厂类,Spring通过该属性知道由哪个工厂类来创建Bean实例。

除此之外,还需要使用factory-method属性来指定静态工厂方法,Spring将调用静态工厂方法返回一个Bean实例,一旦获得了指定Bean实例,Spring后面的处理步骤与采用普通方法创建Bean实例完全一样。如果静态工厂方法需要参数,则使用
<constructor-arg.../>
元素指定静态工厂方法的参数。


调用实例工厂方法创建Bean

实例工厂方法与静态工厂方法只有一个不同:调用静态工厂方法只需使用工厂类即可,而调用实例工厂方法则需要工厂实例。使用实例工厂方法时,配置Bean实例的
<bean.../>
元素无须class属性,配置实例工厂方法使用
factory-bean
指定工厂实例。

采用实例工厂方法创建Bean的
<bean.../>
元素时需要指定如下两个属性:

factory-bean: 该属性的值为工厂Bean的id。

factory-method: 该属性指定实例工厂的工厂方法。

若调用实例工厂方法时需要传入参数,则使用
<constructor-arg.../>
元素确定参数值。


协调作用域不同步的Bean

当singleton作用域的Bean依赖于prototype作用域的Bean时,会产生不同步的现象,原因是因为当Spring容器初始化时,容器会预初始化容器中所有的
singleton Bean
,由于
singleton Bean
依赖于
prototype
Bean
,因此Spring在初始化
singleton Bean
之前,会先创建
prototypeBean
——然后才创建
singleton Bean
,接下里将
prototype
Bean
注入
singleton Bean


解决不同步的方法有两种:

放弃依赖注入: singleton作用域的Bean每次需要prototype作用域的Bean时,主动向容器请求新的Bean实例,即可保证每次注入的
prototype Bean
实例都是最新的实例。

利用方法注入: 方法注入通常使用lookup方法注入,使用lookup方法注入可以让Spring容器重写容器中Bean的抽象或具体方法,返回查找容器中其他Bean的结果,被查找的Bean通常是一个
non-singleton Bean
。Spring通过使用JDK动态代理或cglib库修改客户端的二进制码,从而实现上述要求。

建议采用第二种方法,使用方法注入。为了使用lookup方法注入,大致需要如下两步:

将调用者Bean的实现类定义为抽象类,并定义一个抽象方法来获取被依赖的Bean。

<bean.../>
元素中添加
<lookup-method.../>
子元素让Spring为调用者Bean的实现类实现指定的抽象方法。

注意:

Spring会采用运行时动态增强的方式来实现
<lookup-method.../>
元素所指定的抽象方法,如果目标抽象类实现过接口,Spring会采用JDK动态代理来实现该抽象类,并为之实现抽象方法;如果目标抽象类没有实现过接口,Spring会采用cglib实现该抽象类,并为之实现抽象方法。Spring4.0的spring-core-xxx.jar包中已经集成了cglib类库。


两种后处理器

Spring提供了两种常用的后处理器:

Bean后处理器: 这种后处理器会对容器中Bean进行后处理,对Bean进行额外加强。

容器后处理器: 这种后处理器会对IoC容器进行后处理,用于增强容器功能。


Bean后处理器

Bean后处理器是一种特殊的Bean,这种特殊的Bean并不对外提供服务,它甚至可以无须id属性,它主要负责对容器中的其他Bean执行后处理,例如为容器中的目标Bean生成代理等,这种Bean称为Bean后处理器。Bean后处理器会在Bean实例创建成功之后,对Bean实例进行进一步的增强处理。Bean后处理器必须实现
BeanPostProcessor
接口,同时必须实现该接口的两个方法。

Object postProcessBeforeInitialization(Object bean, String name) throws BeansException
: 该方法的第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean的配置id

Object postProcessAfterinitialization(Object bean, String name) throws BeansException
: 该方法的第一个参数是系统即将进行后处理的Bean实例,第二个参数是该Bean的配置id

容器中一旦注册了Bean后处理器,Bean后处理器就会自动启动,在容器中每个Bean创建时自动工作,Bean后处理器两个方法的回调时机如下图:



注意一点,如果使用
BeanFactory
作为Spring容器,则必须手动注册Bean后处理器,程序必须获取Bean后处理器实例,然后手动注册。
<span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">BeanPostProcessor</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> bp </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">BeanPostProcessor</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">)</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">beanFactory</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">.</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">getBean</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"bp"</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">);</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
beanFactory</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">.</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">addBeanPostProcessor</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">bp</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">);</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">Person</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> p </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="typ" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">Person</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">)</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">beanFactory</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">.</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">getBean</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">(</span><span class="str" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"person"</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">);</span>


容器后处理器

Bean后处理器负责处理容器中的所有Bean实例,而容器后处理器则负责处理容器本身。容器后处理器必须实现
BeanFactoryPostProcessor
接口,并实现该接口的一个方法
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
实现该方法的方法体就是对Spring容器进行的处理,这种处理可以对Spring容器进行自定义扩展,当然也可以对Spring容器不进行任何处理。

类似于
BeanPostProcessor
ApplicationContext
可自动检测到容器中的容器后处理器,并且自动注册容器后处理器。但若使用
BeanFactory
作为Spring容器,则必须手动调用该容器后处理器来处理
BeanFactory
容器。


Spring的"零配置"支持


搜索Bean类

Spring提供如下几个Annotation来标注Spring Bean:

@Component
: 标注一个普通的Spring Bean类

@Controller
: 标注一个控制器组件类

@Service
: 标注一个业务逻辑组件类

@Repository
: 标注一个DAO组件类

在Spring配置文件中做如下配置,指定自动扫描的包:
<span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"><context:component-scan</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">base-package</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"edu.shu.spring.domain"</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">/></span>


使用@Resource配置依赖

@Resource
位于
javax.annotation
包下,是来自JavaEE规范的一个
Annotation
,Spring直接借鉴了该
Annotation
,通过使用该
Annotation
为目标Bean指定协作者Bean。使用
@Resource
<property.../>
元素的ref属性有相同的效果。

@Resource
不仅可以修饰setter方法,也可以直接修饰实例变量,如果使用
@Resource
修饰实例变量将会更加简单,此时Spring将会直接使用JavaEE规范的Field注入,此时连setter方法都可以不要。


使用@PostConstruct和@PreDestroy定制生命周期行为

@PostConstruct
@PreDestroy
同样位于javax.annotation包下,也是来自JavaEE规范的两个Annotation,Spring直接借鉴了它们,用于定制Spring容器中Bean的生命周期行为。它们都用于修饰方法,无须任何属性。其中前者修饰的方法时Bean的初始化方法;而后者修饰的方法时Bean销毁之前的方法。


Spring4.0增强的自动装配和精确装配

Spring提供了
@Autowired
注解来指定自动装配,
@Autowired
可以修饰setter方法、普通方法、实例变量和构造器等。当使用
@Autowired
标注setter方法时,默认采用byType自动装配策略。在这种策略下,符合自动装配类型的候选Bean实例常常有多个,这个时候就可能引起异常,为了实现精确的自动装配,Spring提供了
@Qualifier
注解,通过使用
@Qualifier
,允许根据Bean的id来执行自动装配。


Spring的AOP


为什么需要AOP

AOP(Aspect Orient Programming)也就是面向切面编程,作为面向对象编程的一种补充,已经成为一种比较成熟的编程方式。其实AOP问世的时间并不太长,AOP和OOP互为补充,面向切面编程将程序运行过程分解成各个切面。

AOP专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在JavaEE应用中,常常通过AOP来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等,AOP已经成为一种非常常用的解决方案。


使用AspectJ实现AOP

AspectJ是一个基于Java语言的AOP框架,提供了强大的AOP功能,其他很多AOP框架都借鉴或采纳其中的一些思想。其主要包括两个部分:一个部分定义了如何表达、定义AOP编程中的语法规范,通过这套语法规范,可以方便地用AOP来解决Java语言中存在的交叉关注点的问题;另一个部分是工具部分,包括编译、调试工具等。

AOP实现可分为两类:

静态AOP实现: AOP框架在编译阶段对程序进行修改,即实现对目标类的增强,生成静态的AOP代理类,以AspectJ为代表。

动态AOP实现: AOP框架在运行阶段动态生成AOP代理,以实现对目标对象的增强,以Spring AOP为代表。

一般来说,静态AOP实现具有较好的性能,但需要使用特殊的编译器。动态AOP实现是纯Java实现,因此无须特殊的编译器,但是通常性能略差。


AOP的基本概念

关于面向切面编程的一些术语:

切面(Aspect): 切面用于组织多个Advice,Advice放在切面中定义。

连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用,或者异常的抛出。在Spring AOP中,连接点总是方法的调用。

增强处理(Advice): AOP框架在特定的切入点执行的增强处理。处理有"around"、"before"和"after"等类型

切入点(Pointcut): 可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求时,该连接点将被添加增强处理,该连接点也就变成了切入点。


Spring的AOP支持

Spring中的AOP代理由Spring的IoC容器负责生成、管理,其依赖关系也由IoC容器负责管理。

为了在应用中使用
@AspectJ
支持,Spring需要添加三个库:

aspectjweaver.jar


aspectjrt.jar


aopalliance.jar


并在Spring配置文件中做如下配置:
<span class="com" style="border: 0px; margin: 0px; padding: 0px; color: rgb(136, 0, 0);"><!--启动@AspectJ支持--></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"><aop:aspectj-autoproxy/></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">

</span><span class="com" style="border: 0px; margin: 0px; padding: 0px; color: rgb(136, 0, 0);"><!--指定自动搜索Bean组件、自动搜索切面类--></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"><context:component-scan</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">base-package</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"edu.shu.sprint.service"</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"><context:include-filter</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">type</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"annotation"</span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);"> </span><span class="atn" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 0, 102);">expression</span><span class="pun" style="border: 0px; margin: 0px; padding: 0px; color: rgb(102, 102, 0);">=</span><span class="atv" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 136, 0);">"org.aspectj.lang.annotation.Aspect"</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);">/></span><span class="pln" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 0);">
</span><span class="tag" style="border: 0px; margin: 0px; padding: 0px; color: rgb(0, 0, 136);"></context:component-scan></span>
<p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">69</span><span style="color: rgb(102, 102, 102);">道</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">面试题和答案</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">概述</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">1. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">spring?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">是个</span><span style="color: rgb(102, 102, 102);">java</span><span style="color: rgb(102, 102, 102);">企业级应用的开源开发框架。</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">主要用来开发</span><span style="color: rgb(102, 102, 102);">Java</span><span style="color: rgb(102, 102, 102);">应用,但是有些扩展是针对构建</span><span style="color: rgb(102, 102, 102);">J2EE</span><span style="color: rgb(102, 102, 102);">平台的</span><span style="color: rgb(102, 102, 102);">web</span><span style="color: rgb(102, 102, 102);">应用。</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">框架目标是简化</span><span style="color: rgb(102, 102, 102);">Java</span><span style="color: rgb(102, 102, 102);">企业级应用开发,并通过</span><span style="color: rgb(102, 102, 102);">POJO</span><span style="color: rgb(102, 102, 102);">为基础的编程模型促进良好的编程习惯。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">2. </span><span style="color: rgb(102, 102, 102);">使用</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架的好处是什么?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">轻量:</span></strong><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">是轻量的,基本的版本大约</span><span style="color: rgb(102, 102, 102);">2MB</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">控制反转:</span></strong><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">面向切面的编程</span><span style="color: rgb(102, 102, 102);">(AOP)</span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">支持面向切面的编程,并且把应用业务逻辑和系统服务分开。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">容器:</span></strong><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">包含并管理应用中对象的生命周期和配置。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">MVC</span><span style="color: rgb(102, 102, 102);">框架</span></strong><span style="color: rgb(102, 102, 102);">:</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">WEB</span><span style="color: rgb(102, 102, 102);">框架是个精心设计的框架,是</span><span style="color: rgb(102, 102, 102);">Web</span><span style="color: rgb(102, 102, 102);">框架的一个很好的替代品。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">事务管理:</span></strong><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(</span><span style="color: rgb(102, 102, 102);">JTA</span><span style="color: rgb(102, 102, 102);">)。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">异常处理:</span></strong><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">提供方便的</span><span style="color: rgb(102, 102, 102);">API</span><span style="color: rgb(102, 102, 102);">把具体技术相关的异常(比如由</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);"><a target=_blank href="http://lib.csdn.net/base/17" class="replace_word" title="Java EE知识库" target="_blank" style="text-decoration: none; color: rgb(223, 52, 52); font-weight: bold;">hibernate</a> or JDO</span><span style="color: rgb(102, 102, 102);">抛出的)转化为一致的</span><span style="color: rgb(102, 102, 102);">unchecked </span><span style="color: rgb(102, 102, 102);">异常。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">3.  Spring</span><span style="color: rgb(102, 102, 102);">由哪些模块组成</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">以下是</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">框架的基本模块:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Core module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Bean module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Context module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Expression Language module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">JDBC module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">ORM module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">OXM module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Java Messaging Service(JMS) module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Transaction module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Web module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Web-Servlet module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Web-Struts module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Web-Portlet module</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">4. </span><span style="color: rgb(102, 102, 102);">核心容器(应用上下文</span><span style="color: rgb(102, 102, 102);">) </span><span style="color: rgb(102, 102, 102);">模块。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">这是基本的</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">模块,提供</span><span style="color: rgb(102, 102, 102);">spring </span><span style="color: rgb(102, 102, 102);">框架的基础功能,</span><span style="color: rgb(102, 102, 102);">BeanFactory </span><span style="color: rgb(102, 102, 102);">是</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">任何以</span><span style="color: rgb(102, 102, 102);">spring</span><span style="color: rgb(102, 102, 102);">为基础的应用的核心。</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">框架建立在此模块之上,它使</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">成为一个容器。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">5. BeanFactory – BeanFactory </span><span style="color: rgb(102, 102, 102);">实现举例。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Bean </span><span style="color: rgb(102, 102, 102);">工厂是工厂模式的一个实现,提供了控制反转功能,用来把应用的配置和依赖从正真的应用代码中分离。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">最常用的</span><span style="color: rgb(102, 102, 102);">BeanFactory </span><span style="color: rgb(102, 102, 102);">实现是</span><span style="color: rgb(102, 102, 102);">XmlBeanFactory </span><span style="color: rgb(102, 102, 102);">类。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">6. XMLBeanFactory </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">最常用的就是</span><span style="color: rgb(102, 102, 102);">org.springframework.beans.factory.xml.XmlBeanFactory </span><span style="color: rgb(102, 102, 102);">,它根据</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件中的定义加载</span><span style="color: rgb(102, 102, 102);">beans</span><span style="color: rgb(102, 102, 102);">。该容器从</span><span style="color: rgb(102, 102, 102);">XML </span><span style="color: rgb(102, 102, 102);">文件读取配置元数据并用它去创建一个完全配置的系统或应用。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">7. </span><span style="color: rgb(102, 102, 102);">解释</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">模块</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">模块用于发给我们的</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">应用做面向切面的开发,</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">很多支持由</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">联盟提供,这样就确保了</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">和其他</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">框架的共通性。这个模块将元数据编程引入</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">8. </span><span style="color: rgb(102, 102, 102);">解释</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">抽象和</span><span style="color: rgb(102, 102, 102);">DAO</span><span style="color: rgb(102, 102, 102);">模块。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">通过使用</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">抽象和</span><span style="color: rgb(102, 102, 102);">DAO</span><span style="color: rgb(102, 102, 102);">模块,保证<a target=_blank href="http://lib.csdn.net/base/14" class="replace_word" title="MySQL知识库" target="_blank" style="text-decoration: none; color: rgb(223, 52, 52); font-weight: bold;">数据库</a>代码的简洁,并能避免数据库资源错误关闭导致的问题,它在各种不同的数据库的错误信息之上,提供了一个统一的异常访问层。它还利用</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">AOP </span><span style="color: rgb(102, 102, 102);">模块给</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">应用中的对象提供事务管理服务。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">9. </span><span style="color: rgb(102, 102, 102);">解释对象</span><span style="color: rgb(102, 102, 102);">/</span><span style="color: rgb(102, 102, 102);">关系映射集成模块。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">通过提供</span><span style="color: rgb(102, 102, 102);">ORM</span><span style="color: rgb(102, 102, 102);">模块,支持我们在直接</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">之上使用一个对象</span><span style="color: rgb(102, 102, 102);">/</span><span style="color: rgb(102, 102, 102);">关系映射映射</span><span style="color: rgb(102, 102, 102);">(ORM)</span><span style="color: rgb(102, 102, 102);">工具,</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">支持集成主流的</span><span style="color: rgb(102, 102, 102);">ORM</span><span style="color: rgb(102, 102, 102);">框架,如</span><span style="color: rgb(102, 102, 102);">Hiberate,JDO</span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);"> iBATIS SQL Maps</span><span style="color: rgb(102, 102, 102);">。</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的事务管理同样支持以上所有</span><span style="color: rgb(102, 102, 102);">ORM</span><span style="color: rgb(102, 102, 102);">框架及</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">10.  </span><span style="color: rgb(102, 102, 102);">解释</span><span style="color: rgb(102, 102, 102);">WEB </span><span style="color: rgb(102, 102, 102);">模块。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">WEB</span><span style="color: rgb(102, 102, 102);">模块是构建在</span><span style="color: rgb(102, 102, 102);">application context </span><span style="color: rgb(102, 102, 102);">模块基础之上,提供一个适合</span><span style="color: rgb(102, 102, 102);">web</span><span style="color: rgb(102, 102, 102);">应用的上下文。这个模块也包括支持多种面向</span><span style="color: rgb(102, 102, 102);">web</span><span style="color: rgb(102, 102, 102);">的任务,如透明地处理多个文件上传请求和程序级请求参数的绑定到你的业务对象。它也有对</span><span style="color: rgb(102, 102, 102);">Jakarta Struts</span><span style="color: rgb(102, 102, 102);">的支持。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">12.  Spring</span><span style="color: rgb(102, 102, 102);">配置文件</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">配置文件是个</span><span style="color: rgb(102, 102, 102);">XML </span><span style="color: rgb(102, 102, 102);">文件,这个文件包含了类信息,描述了如何配置它们,以及如何相互调用。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">13.  </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">Spring IOC </span><span style="color: rgb(102, 102, 102);">容器?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring IOC </span><span style="color: rgb(102, 102, 102);">负责创建对象,管理对象(通过依赖注入(</span><span style="color: rgb(102, 102, 102);">DI</span><span style="color: rgb(102, 102, 102);">),装配对象,配置对象,并且管理这些对象的整个生命周期。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">14.  IOC</span><span style="color: rgb(102, 102, 102);">的优点是什么?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">IOC </span><span style="color: rgb(102, 102, 102);">或</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">依赖注入把应用的代码量降到最低。它使应用容易测试,单元测试不再需要单例和</span><span style="color: rgb(102, 102, 102);">JNDI</span><span style="color: rgb(102, 102, 102);">查找机制。最小的代价和最小的侵入性使松散耦合得以实现。</span><span style="color: rgb(102, 102, 102);">IOC</span><span style="color: rgb(102, 102, 102);">容器支持加载服务时的饿汉式初始化和懒加载。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">15. ApplicationContext</span><span style="color: rgb(102, 102, 102);">通常的实现是什么</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">FileSystemXmlApplicationContext </span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">此容器从一个</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件中加载</span><span style="color: rgb(102, 102, 102);">beans</span><span style="color: rgb(102, 102, 102);">的定义,</span><span style="color: rgb(102, 102, 102);">XML Bean </span><span style="color: rgb(102, 102, 102);">配置文件的全路径名必须提供给它的构造函数。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">ClassPathXmlApplicationContext</span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">此容器也从一个</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件中加载</span><span style="color: rgb(102, 102, 102);">beans</span><span style="color: rgb(102, 102, 102);">的定义,这里,你需要正确设置</span><span style="color: rgb(102, 102, 102);">classpath</span><span style="color: rgb(102, 102, 102);">因为这个容器将在</span><span style="color: rgb(102, 102, 102);">classpath</span><span style="color: rgb(102, 102, 102);">里找</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">配置。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">WebXmlApplicationContext</span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">此容器加载一个</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件,此文件定义了一个</span><span style="color: rgb(102, 102, 102);">WEB</span><span style="color: rgb(102, 102, 102);">应用的所有</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">16. Bean </span><span style="color: rgb(102, 102, 102);">工厂和</span><span style="color: rgb(102, 102, 102);"> Application contexts  </span><span style="color: rgb(102, 102, 102);">有什么区别?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Application contexts</span><span style="color: rgb(102, 102, 102);">提供一种方法处理文本消息,一个通常的做法是加载文件资源(比如镜像),它们可以向注册为监听器的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">发布事件。另外,在容器或容器内的对象上执行的那些不得不由</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">工厂以程序化方式处理的操作,可以在</span><span style="color: rgb(102, 102, 102);">Application contexts</span><span style="color: rgb(102, 102, 102);">中以声明的方式处理。</span><span style="color: rgb(102, 102, 102);">Application contexts</span><span style="color: rgb(102, 102, 102);">实现了</span><span style="color: rgb(102, 102, 102);">MessageSource</span><span style="color: rgb(102, 102, 102);">接口,该接口的实现以可插拔的方式提供获取本地化消息的方法。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">17. </span><span style="color: rgb(102, 102, 102);">一个</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的应用看起来象什么?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">一个定义了一些功能的接口。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">这实现包括属性,它的</span><span style="color: rgb(102, 102, 102);">Setter </span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);"> getter </span><span style="color: rgb(102, 102, 102);">方法和函数等。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Spring AOP</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">XML </span><span style="color: rgb(102, 102, 102);">配置文件。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">使用以上功能的客户端程序。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">依赖注入</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">18. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的依赖注入?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">依赖注入,是</span><span style="color: rgb(102, 102, 102);">IOC</span><span style="color: rgb(102, 102, 102);">的一个方面,是个通常的概念,它有多种解释。这概念是说你不用创建对象,而只需要描述它如何被创建。你不在代码里直接组装你的组件和服务,但是要在配置文件里描述哪些组件需要哪些服务,之后一个容器(</span><span style="color: rgb(102, 102, 102);">IOC</span><span style="color: rgb(102, 102, 102);">容器)负责把他们组装起来。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">19.  </span><span style="color: rgb(102, 102, 102);">有哪些不同类型的</span><span style="color: rgb(102, 102, 102);">IOC</span><span style="color: rgb(102, 102, 102);">(依赖注入)方式?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">构造器依赖注入:</span></strong><span style="color: rgb(102, 102, 102);">构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">Setter</span><span style="color: rgb(102, 102, 102);">方法注入:</span></strong><span style="color: rgb(102, 102, 102);">Setter</span><span style="color: rgb(102, 102, 102);">方法注入是容器通过调用无参构造器或无参</span><span style="color: rgb(102, 102, 102);">static</span><span style="color: rgb(102, 102, 102);">工厂</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">方法实例化</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">之后,调用该</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">setter</span><span style="color: rgb(102, 102, 102);">方法,即实现了基于</span><span style="color: rgb(102, 102, 102);">setter</span><span style="color: rgb(102, 102, 102);">的依赖注入。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">20. </span><span style="color: rgb(102, 102, 102);">哪种依赖注入方式你建议使用,构造器注入,还是</span><span style="color: rgb(102, 102, 102);"> Setter</span><span style="color: rgb(102, 102, 102);">方法注入?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">你两种依赖方式都可以使用,构造器注入和</span><span style="color: rgb(102, 102, 102);">Setter</span><span style="color: rgb(102, 102, 102);">方法注入。最好的解决方案是用构造器参数实现强制依赖,</span><span style="color: rgb(102, 102, 102);">setter</span><span style="color: rgb(102, 102, 102);">方法实现可选依赖。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">Spring Beans</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">21.</span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">Spring beans?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring beans </span><span style="color: rgb(102, 102, 102);">是那些形成</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">应用的主干的</span><span style="color: rgb(102, 102, 102);">java</span><span style="color: rgb(102, 102, 102);">对象。它们被</span><span style="color: rgb(102, 102, 102);">Spring IOC</span><span style="color: rgb(102, 102, 102);">容器初始化,装配,和管理。这些</span><span style="color: rgb(102, 102, 102);">beans</span><span style="color: rgb(102, 102, 102);">通过容器中配置的元数据创建。比如,以</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件中</span><span style="color: rgb(102, 102, 102);"><bean/> </span><span style="color: rgb(102, 102, 102);">的形式定义。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">框架定义的</span><span style="color: rgb(102, 102, 102);">beans</span><span style="color: rgb(102, 102, 102);">都是单件</span><span style="color: rgb(102, 102, 102);">beans</span><span style="color: rgb(102, 102, 102);">。在</span><span style="color: rgb(102, 102, 102);">bean tag</span><span style="color: rgb(102, 102, 102);">中有个属性</span><span style="color: rgb(102, 102, 102);">”singleton”</span><span style="color: rgb(102, 102, 102);">,如果它被赋为</span><span style="color: rgb(102, 102, 102);">TRUE</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">bean </span><span style="color: rgb(102, 102, 102);">就是单件,否则就是一个</span><span style="color: rgb(102, 102, 102);"> prototype bean</span><span style="color: rgb(102, 102, 102);">。默认是</span><span style="color: rgb(102, 102, 102);">TRUE</span><span style="color: rgb(102, 102, 102);">,所以所有在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架中的</span><span style="color: rgb(102, 102, 102);">beans </span><span style="color: rgb(102, 102, 102);">缺省都是单件。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">22. </span><span style="color: rgb(102, 102, 102);">一个</span><span style="color: rgb(102, 102, 102);"> Spring Bean </span><span style="color: rgb(102, 102, 102);">定义</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">包含什么?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">一个</span><span style="color: rgb(102, 102, 102);">Spring Bean </span><span style="color: rgb(102, 102, 102);">的定义包含容器必知的所有配置元数据,包括如何创建一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">,它的生命周期详情及它的依赖。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">23. </span><span style="color: rgb(102, 102, 102);">如何给</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">容器提供配置元数据</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">这里有三种重要的方法给</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">容器提供配置元数据。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">配置文件。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">基于注解的配置。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">基于</span><span style="color: rgb(102, 102, 102);">java</span><span style="color: rgb(102, 102, 102);">的配置。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">24. </span><span style="color: rgb(102, 102, 102);">你怎样定义类的作用域</span><span style="color: rgb(102, 102, 102);">? </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">当定义一个</span><span style="color: rgb(102, 102, 102);"><bean> </span><span style="color: rgb(102, 102, 102);">在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">里,我们还能给这个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">声明一个作用域。它可以通过</span><span style="color: rgb(102, 102, 102);">bean </span><span style="color: rgb(102, 102, 102);">定义中的</span><span style="color: rgb(102, 102, 102);">scope</span><span style="color: rgb(102, 102, 102);">属性来定义。如,当</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">要在需要的时候每次生产一个新的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">实例,</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">scope</span><span style="color: rgb(102, 102, 102);">属性被指定为</span><span style="color: rgb(102, 102, 102);">prototype</span><span style="color: rgb(102, 102, 102);">。另一方面,一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">每次使用的时候必须返回同一个实例,这个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">scope </span><span style="color: rgb(102, 102, 102);">属性</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">必须设为</span><span style="color: rgb(102, 102, 102);"> singleton</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">25. </span><span style="color: rgb(102, 102, 102);">解释</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">支持的几种</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的作用域。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架支持以下五种</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的作用域:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">singleton : </span></strong><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">在每个</span><span style="color: rgb(102, 102, 102);">Spring ioc </span><span style="color: rgb(102, 102, 102);">容器中只有一个实例。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">prototype</span></strong><span style="color: rgb(102, 102, 102);">:一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的定义可以有多个实例。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">request</span></strong><span style="color: rgb(102, 102, 102);">:每次</span><span style="color: rgb(102, 102, 102);">http</span><span style="color: rgb(102, 102, 102);">请求都会创建一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">,该作用域仅在基于</span><span style="color: rgb(102, 102, 102);">web</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">Spring ApplicationContext</span><span style="color: rgb(102, 102, 102);">情形下有效。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">session</span></strong><span style="color: rgb(102, 102, 102);">:在一个</span><span style="color: rgb(102, 102, 102);">HTTP Session</span><span style="color: rgb(102, 102, 102);">中,一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">定义对应一个实例。该作用域仅在基于</span><span style="color: rgb(102, 102, 102);">web</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">Spring ApplicationContext</span><span style="color: rgb(102, 102, 102);">情形下有效。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">global-session</span></strong><span style="color: rgb(102, 102, 102);">:在一个全局的</span><span style="color: rgb(102, 102, 102);">HTTP Session</span><span style="color: rgb(102, 102, 102);">中,一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">定义对应一个实例。该作用域仅在基于</span><span style="color: rgb(102, 102, 102);">web</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">Spring ApplicationContext</span><span style="color: rgb(102, 102, 102);">情形下有效。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">缺省的</span><span style="color: rgb(102, 102, 102);">Spring bean </span><span style="color: rgb(102, 102, 102);">的作用域是</span><span style="color: rgb(102, 102, 102);">Singleton.</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">26. Spring</span><span style="color: rgb(102, 102, 102);">框架中的单例</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">是线程安全的吗</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">不,</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架中的单例</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">不是线程安全的。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">27. </span><span style="color: rgb(102, 102, 102);">解释</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架中</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的生命周期。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">容器</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">从</span><span style="color: rgb(102, 102, 102);">XML </span><span style="color: rgb(102, 102, 102);">文件中读取</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的定义,并实例化</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">根据</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的定义填充所有的属性。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">如果</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">实现了</span><span style="color: rgb(102, 102, 102);">BeanNameAware </span><span style="color: rgb(102, 102, 102);">接口,</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">传递</span><span style="color: rgb(102, 102, 102);">bean </span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">ID </span><span style="color: rgb(102, 102, 102);">到</span><span style="color: rgb(102, 102, 102);"> setBeanName</span><span style="color: rgb(102, 102, 102);">方法。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">如果</span><span style="color: rgb(102, 102, 102);">Bean </span><span style="color: rgb(102, 102, 102);">实现了</span><span style="color: rgb(102, 102, 102);"> BeanFactoryAware </span><span style="color: rgb(102, 102, 102);">接口,</span><span style="color: rgb(102, 102, 102);"> Spring</span><span style="color: rgb(102, 102, 102);">传递</span><span style="color: rgb(102, 102, 102);">beanfactory </span><span style="color: rgb(102, 102, 102);">给</span><span style="color: rgb(102, 102, 102);">setBeanFactory </span><span style="color: rgb(102, 102, 102);">方法。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">如果有任何与</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">相关联的</span><span style="color: rgb(102, 102, 102);">BeanPostProcessors</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">会在</span><span style="color: rgb(102, 102, 102);">postProcesserBeforeInitialization()</span><span style="color: rgb(102, 102, 102);">方法内调用它们。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">如果</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">实现</span><span style="color: rgb(102, 102, 102);">IntializingBean</span><span style="color: rgb(102, 102, 102);">了,调用它的</span><span style="color: rgb(102, 102, 102);">afterPropertySet</span><span style="color: rgb(102, 102, 102);">方法,如果</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">声明了初始化方法,调用此初始化方法。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">如果有</span><span style="color: rgb(102, 102, 102);">BeanPostProcessors </span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);">bean </span><span style="color: rgb(102, 102, 102);">关联,这些</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">postProcessAfterInitialization() </span><span style="color: rgb(102, 102, 102);">方法将被调用。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">如果</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">实现了</span><span style="color: rgb(102, 102, 102);"> DisposableBean</span><span style="color: rgb(102, 102, 102);">,它将调用</span><span style="color: rgb(102, 102, 102);">destroy()</span><span style="color: rgb(102, 102, 102);">方法。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">28.  </span><span style="color: rgb(102, 102, 102);">哪些是重要的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">生命周期方法?</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">你能重载它们吗?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">有两个重要的</span><span style="color: rgb(102, 102, 102);">bean </span><span style="color: rgb(102, 102, 102);">生命周期方法,第一个是</span><span style="color: rgb(102, 102, 102);">setup </span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">它是在容器加载</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的时候被调用。第二个方法是</span><span style="color: rgb(102, 102, 102);"> teardown  </span><span style="color: rgb(102, 102, 102);">它是在容器卸载类的时候被调用。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">The bean </span><span style="color: rgb(102, 102, 102);">标签有两个重要的属性(</span><span style="color: rgb(102, 102, 102);">init-method</span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);">destroy-method</span><span style="color: rgb(102, 102, 102);">)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(</span><span style="color: rgb(102, 102, 102);">@PostConstruct</span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);">@PreDestroy</span><span style="color: rgb(102, 102, 102);">)。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">29. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的内部</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">当一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">仅被用作另一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的属性时,它能被声明为一个内部</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">,为了定义</span><span style="color: rgb(102, 102, 102);">inner bean</span><span style="color: rgb(102, 102, 102);">,在</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">基于</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">配置元数据中,可以在</span><span style="color: rgb(102, 102, 102);"> <property/></span><span style="color: rgb(102, 102, 102);">或</span><span style="color: rgb(102, 102, 102);"> <constructor-arg/> </span><span style="color: rgb(102, 102, 102);">元素内使用</span><span style="color: rgb(102, 102, 102);"><bean/> </span><span style="color: rgb(102, 102, 102);">元素,内部</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">通常是匿名的,它们的</span><span style="color: rgb(102, 102, 102);">Scope</span><span style="color: rgb(102, 102, 102);">一般是</span><span style="color: rgb(102, 102, 102);">prototype</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">30. </span><span style="color: rgb(102, 102, 102);">在</span><span style="color: rgb(102, 102, 102);"> Spring</span><span style="color: rgb(102, 102, 102);">中如何注入一个</span><span style="color: rgb(102, 102, 102);">java</span><span style="color: rgb(102, 102, 102);">集合?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">提供以下几种集合的配置元素:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);"><list></span><span style="color: rgb(102, 102, 102);">类型用于注入一列值,允许有相同的值。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);"><set> </span><span style="color: rgb(102, 102, 102);">类型用于注入一组值,不允许有相同的值。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);"><map> </span><span style="color: rgb(102, 102, 102);">类型用于注入一组键值对,键和值都可以为任意类型。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);"><props></span><span style="color: rgb(102, 102, 102);">类型用于注入一组键值对,键和值都只能为</span><span style="color: rgb(102, 102, 102);">String</span><span style="color: rgb(102, 102, 102);">类型。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">31. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">装配</span><span style="color: rgb(102, 102, 102);">? </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">装配,或</span><span style="color: rgb(102, 102, 102);">bean </span><span style="color: rgb(102, 102, 102);">装配是指在</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">容器中把</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">组装到一起,前提是容器需要知道</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的依赖关系,如何通过依赖注入来把它们装配到一起。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">32. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的自动装配?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">容器能够自动装配相互合作的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">,这意味着容器不需要</span><span style="color: rgb(102, 102, 102);"><constructor-arg></span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);"><property></span><span style="color: rgb(102, 102, 102);">配置,能通过</span><span style="color: rgb(102, 102, 102);">Bean</span><span style="color: rgb(102, 102, 102);">工厂自动处理</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">之间的协作。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">33. </span><span style="color: rgb(102, 102, 102);">解释不同方式的自动装配</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">有五种自动装配的方式,可以用来指导</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">容器用自动装配方式来进行依赖注入。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">no</span></strong><span style="color: rgb(102, 102, 102);">:默认的方式是不进行自动装配,通过显式设置</span><span style="color: rgb(102, 102, 102);">ref </span><span style="color: rgb(102, 102, 102);">属性来进行装配。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">byName</span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">通过参数名</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">自动装配,</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">容器在配置文件中发现</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">autowire</span><span style="color: rgb(102, 102, 102);">属性被设置成</span><span style="color: rgb(102, 102, 102);">byname</span><span style="color: rgb(102, 102, 102);">,之后容器试图匹配、装配和该</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的属性具有相同名字的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">byType:</span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">通过参数类型自动装配,</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">容器在配置文件中发现</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">autowire</span><span style="color: rgb(102, 102, 102);">属性被设置成</span><span style="color: rgb(102, 102, 102);">byType</span><span style="color: rgb(102, 102, 102);">,之后容器试图匹配、装配和该</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的属性具有相同类型的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">。如果有多个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">符合条件,则抛出错误。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">constructor</span><span style="color: rgb(102, 102, 102);">:这个方式类似于</span></strong><span style="color: rgb(102, 102, 102);">byType</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">但是要提供给构造器参数,如果没有确定的带参数的构造器参数类型,将会抛出异常。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">autodetect</span><span style="color: rgb(102, 102, 102);">:</span></strong><span style="color: rgb(102, 102, 102);">首先尝试使用</span><span style="color: rgb(102, 102, 102);">constructor</span><span style="color: rgb(102, 102, 102);">来自动装配,如果无法工作,则使用</span><span style="color: rgb(102, 102, 102);">byType</span><span style="color: rgb(102, 102, 102);">方式。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">34.</span><span style="color: rgb(102, 102, 102);">自动装配有哪些局限性</span><span style="color: rgb(102, 102, 102);"> ?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">自动装配的局限性是:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">重写</span></strong><span style="color: rgb(102, 102, 102);">:</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">你仍需用</span><span style="color: rgb(102, 102, 102);"> <constructor-arg></span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);"> <property> </span><span style="color: rgb(102, 102, 102);">配置来定义依赖,意味着总要重写自动装配。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">基本数据类型</span></strong><span style="color: rgb(102, 102, 102);">:你不能自动装配简单的属性,如基本数据类型,</span><span style="color: rgb(102, 102, 102);">String</span><span style="color: rgb(102, 102, 102);">字符串,和类。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">模糊特性:</span></strong><span style="color: rgb(102, 102, 102);">自动装配不如显式装配精确,如果有可能,建议使用显式装配。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">35. </span><span style="color: rgb(102, 102, 102);">你可以在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">中注入一个</span><span style="color: rgb(102, 102, 102);">null </span><span style="color: rgb(102, 102, 102);">和一个空字符串吗?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">可以。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">注解</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">36. </span><span style="color: rgb(102, 102, 102);">什么是基于</span><span style="color: rgb(102, 102, 102);">Java</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">注解配置</span><span style="color: rgb(102, 102, 102);">? </span><span style="color: rgb(102, 102, 102);">给一些注解的例子</span><span style="color: rgb(102, 102, 102);">.</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">基于</span><span style="color: rgb(102, 102, 102);">Java</span><span style="color: rgb(102, 102, 102);">的配置,允许你在少量的</span><span style="color: rgb(102, 102, 102);">Java</span><span style="color: rgb(102, 102, 102);">注解的帮助下,进行你的大部分</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">配置而非通过</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">以</span><span style="color: rgb(102, 102, 102);">@Configuration </span><span style="color: rgb(102, 102, 102);">注解为例,它用来标记类可以当做一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的定义,被</span><span style="color: rgb(102, 102, 102);">Spring IOC</span><span style="color: rgb(102, 102, 102);">容器使用。另一个例子是</span><span style="color: rgb(102, 102, 102);">@Bean</span><span style="color: rgb(102, 102, 102);">注解,它表示此方法将要返回一个对象,作为一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">注册进</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">应用上下文。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">37. </span><span style="color: rgb(102, 102, 102);">什么是基于注解的容器配置</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">相对于</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">文件,注解型的配置依赖于通过字节码元数据装配组件,而非尖括号的声明。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">开发者通过在相应的类,方法或属性上使用注解的方式,直接组件类中进行配置,而不是使用</span><span style="color: rgb(102, 102, 102);">xml</span><span style="color: rgb(102, 102, 102);">表述</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的装配关系。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">38. </span><span style="color: rgb(102, 102, 102);">怎样开启注解装配?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">配置文件中配置</span><span style="color: rgb(102, 102, 102);"> <context:annotation-config/></span><span style="color: rgb(102, 102, 102);">元素。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">39. @Required  </span><span style="color: rgb(102, 102, 102);">注解</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">这个注解表明</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">的属性必须在配置的时候设置,通过一个</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">定义的显式的属性值或通过自动装配,若</span><span style="color: rgb(102, 102, 102);">@Required</span><span style="color: rgb(102, 102, 102);">注解的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">属性未被设置,容器将抛出</span><span style="color: rgb(102, 102, 102);">BeanInitializationException</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">40. @Autowired </span><span style="color: rgb(102, 102, 102);">注解</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">@Autowired </span><span style="color: rgb(102, 102, 102);">注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和</span><span style="color: rgb(102, 102, 102);">@Required</span><span style="color: rgb(102, 102, 102);">一样,修饰</span><span style="color: rgb(102, 102, 102);">setter</span><span style="color: rgb(102, 102, 102);">方法、构造器、属性或者具有任意名称和</span><span style="color: rgb(102, 102, 102);">/</span><span style="color: rgb(102, 102, 102);">或多个参数的</span><span style="color: rgb(102, 102, 102);">PN</span><span style="color: rgb(102, 102, 102);">方法。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">41. @Qualifier </span><span style="color: rgb(102, 102, 102);">注解</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">当有多个相同类型的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">却只有一个需要自动装配时,将</span><span style="color: rgb(102, 102, 102);">@Qualifier </span><span style="color: rgb(102, 102, 102);">注解和</span><span style="color: rgb(102, 102, 102);">@Autowire </span><span style="color: rgb(102, 102, 102);">注解结合使用以消除这种混淆,指定需要装配的确切的</span><span style="color: rgb(102, 102, 102);">bean</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">数据访问</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">42.</span><span style="color: rgb(102, 102, 102);">在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架中如何更有效地使用</span><span style="color: rgb(102, 102, 102);">JDBC? </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">使用</span><span style="color: rgb(102, 102, 102);">SpringJDBC </span><span style="color: rgb(102, 102, 102);">框架,资源管理和错误处理的代价都会被减轻。所以开发者只需写</span><span style="color: rgb(102, 102, 102);">statements </span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);"> queries</span><span style="color: rgb(102, 102, 102);">从数据存取数据,</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">也可以在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架提供的模板类的帮助下更有效地被使用,这个模板叫</span><span style="color: rgb(102, 102, 102);">JdbcTemplate </span><span style="color: rgb(102, 102, 102);">(例子见这里</span><a target=_blank target="_blank" href="http://examples.javacodegeeks.com/enterprise-java/spring/jdbc/spring-jdbctemplate-example/" style="text-decoration: none; color: rgb(12, 137, 207);"><span style="color: rgb(0, 161, 158);">here</span></a><span style="color: rgb(102, 102, 102);">)</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">43. JdbcTemplate</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">JdbcTemplate </span><span style="color: rgb(102, 102, 102);">类提供了很多便利的方法解决诸如把数据库数据转变成基本数据类型或对象,执行写好的或可调用的数据库操作语句,提供自定义的数据错误处理。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">44. Spring</span><span style="color: rgb(102, 102, 102);">对</span><span style="color: rgb(102, 102, 102);">DAO</span><span style="color: rgb(102, 102, 102);">的支持</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">对数据访问对象(</span><span style="color: rgb(102, 102, 102);">DAO</span><span style="color: rgb(102, 102, 102);">)的支持旨在简化它和数据访问技术如</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">Hibernate or JDO </span><span style="color: rgb(102, 102, 102);">结合使用。这使我们可以方便切换持久层。编码时也不用担心会捕获每种技术特有的异常。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">45. </span><span style="color: rgb(102, 102, 102);">使用</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">通过什么方式访问</span><span style="color: rgb(102, 102, 102);">Hibernate? </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">在</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">中有两种方式访问</span><span style="color: rgb(102, 102, 102);">Hibernate</span><span style="color: rgb(102, 102, 102);">:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">控制反转</span><span style="color: rgb(102, 102, 102);">  Hibernate Template</span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);"> Callback</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">继承</span><span style="color: rgb(102, 102, 102);"> HibernateDAOSupport</span><span style="color: rgb(102, 102, 102);">提供一个</span><span style="color: rgb(102, 102, 102);">AOP </span><span style="color: rgb(102, 102, 102);">拦截器。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">46. Spring</span><span style="color: rgb(102, 102, 102);">支持的</span><span style="color: rgb(102, 102, 102);">ORM</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">支持以下</span><span style="color: rgb(102, 102, 102);">ORM</span><span style="color: rgb(102, 102, 102);">:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">Hibernate</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">iBatis</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">JPA (Java Persistence API)</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">TopLink</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">JDO (Java Data Objects)</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">OJB</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">47.</span><span style="color: rgb(102, 102, 102);">如何通过</span><span style="color: rgb(102, 102, 102);">HibernateDaoSupport</span><span style="color: rgb(102, 102, 102);">将</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);">Hibernate</span><span style="color: rgb(102, 102, 102);">结合起来?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">用</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);"> SessionFactory </span><span style="color: rgb(102, 102, 102);">调用</span><span style="color: rgb(102, 102, 102);"> LocalSessionFactory</span><span style="color: rgb(102, 102, 102);">。集成过程分三步:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">配置</span><span style="color: rgb(102, 102, 102);">the Hibernate SessionFactory</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">继承</span><span style="color: rgb(102, 102, 102);">HibernateDaoSupport</span><span style="color: rgb(102, 102, 102);">实现一个</span><span style="color: rgb(102, 102, 102);">DAO</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">在</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">支持的事务中装配。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">48. Spring</span><span style="color: rgb(102, 102, 102);">支持的事务管理类型</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">支持两种类型的事务管理:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">编程式事务管理</span></strong><span style="color: rgb(102, 102, 102);">:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">声明式事务管理:</span></strong><span style="color: rgb(102, 102, 102);">这意味着你可以将业务代码和事务管理分离,你只需用注解和</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">配置来管理事务。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">49. Spring</span><span style="color: rgb(102, 102, 102);">框架的事务管理有哪些优点?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">它为不同的事务</span><span style="color: rgb(102, 102, 102);">API  </span><span style="color: rgb(102, 102, 102);">如</span><span style="color: rgb(102, 102, 102);"> JTA</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">JDBC</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">Hibernate</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">JPA </span><span style="color: rgb(102, 102, 102);">和</span><span style="color: rgb(102, 102, 102);">JDO</span><span style="color: rgb(102, 102, 102);">,提供一个不变的编程模式。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">它为编程式事务管理提供了一套简单的</span><span style="color: rgb(102, 102, 102);">API</span><span style="color: rgb(102, 102, 102);">而不是一些复杂的事务</span><span style="color: rgb(102, 102, 102);">API</span><span style="color: rgb(102, 102, 102);">如</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">它支持声明式事务管理。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><span style="color: rgb(102, 102, 102);">它和</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">各种数据访问抽象层很好得集成。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">50. </span><span style="color: rgb(102, 102, 102);">你更倾向用那种事务管理类型?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">大多数</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">面向切面编程(</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">)</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">51.  </span><span style="color: rgb(102, 102, 102);">解释</span><span style="color: rgb(102, 102, 102);">AOP</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">面向切面的编程,或</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);"> </span><span style="color: rgb(102, 102, 102);">是一种编程技术,允许程序模块化横向切割关注点,或横切典型的责任划分,如日志和事务管理。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">52. Aspect </span><span style="color: rgb(102, 102, 102);">切面</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">核心就是切面,它将多个类的通用行为封装成可重用的模块,该模块含有一组</span><span style="color: rgb(102, 102, 102);">API</span><span style="color: rgb(102, 102, 102);">提供横切功能。比如,一个日志模块可以被称作日志的</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">切面。根据需求的不同,一个应用程序可以有若干切面。在</span><span style="color: rgb(102, 102, 102);">Spring AOP</span><span style="color: rgb(102, 102, 102);">中,切面通过带有</span><span style="color: rgb(102, 102, 102);">@Aspect</span><span style="color: rgb(102, 102, 102);">注解的类实现。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">52. </span><span style="color: rgb(102, 102, 102);">在</span><span style="color: rgb(102, 102, 102);">Spring AOP </span><span style="color: rgb(102, 102, 102);">中,关注点和横切关注的区别是什么?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">关注点是应用中一个模块的行为,一个关注点可能会被定义成一个我们想实现的一个功能。</span><span style="color: rgb(102, 102, 102);">
</span><span style="color: rgb(102, 102, 102);">横切关注点是一个关注点,此关注点是整个应用都会使用的功能,并影响整个应用,比如日志,安全和数据传输,几乎应用的每个模块都需要的功能。因此这些都属于横切关注点。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">54. </span><span style="color: rgb(102, 102, 102);">连接点</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">连接点代表一个应用程序的某个位置,在这个位置我们可以插入一个</span><span style="color: rgb(102, 102, 102);">AOP</span><span style="color: rgb(102, 102, 102);">切面,它实际上是个应用程序执行</span><span style="color: rgb(102, 102, 102);">Spring AOP</span><span style="color: rgb(102, 102, 102);">的位置。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">55. </span><span style="color: rgb(102, 102, 102);">通知</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">通知是个在方法执行前或执行后要做的动作,实际上是程序执行时要通过</span><span style="color: rgb(102, 102, 102);">SpringAOP</span><span style="color: rgb(102, 102, 102);">框架触发的代码段。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">切面可以应用五种类型的通知:</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">before</span></strong><span style="color: rgb(102, 102, 102);">:前置通知,在一个方法执行前被调用。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">after: </span></strong><span style="color: rgb(102, 102, 102);">在方法执行之后调用的通知,无论方法执行是否成功。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">after-returning: </span></strong><span style="color: rgb(102, 102, 102);">仅当方法成功完成后执行的通知。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">after-throwing: </span></strong><span style="color: rgb(102, 102, 102);">在方法抛出异常退出时执行的通知。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">·        </span><strong><span style="color: rgb(102, 102, 102);">around: </span></strong><span style="color: rgb(102, 102, 102);">在方法执行之前和之后调用的通知。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">56. </span><span style="color: rgb(102, 102, 102);">切点</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">切入点是一个或一组连接点,通知将在这些位置执行。可以通过表达式或匹配的方式指明切入点。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">57. </span><span style="color: rgb(102, 102, 102);">什么是引入</span><span style="color: rgb(102, 102, 102);">? </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">引入允许我们在已存在的类中增加新的方法和属性。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">58. </span><span style="color: rgb(102, 102, 102);">什么是目标对象</span><span style="color: rgb(102, 102, 102);">? </span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">被一个或者多个切面所通知的对象。它通常是一个代理对象。也指被通知(</span><span style="color: rgb(102, 102, 102);">advised</span><span style="color: rgb(102, 102, 102);">)对象。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">59. </span><span style="color: rgb(102, 102, 102);">什么是代理</span><span style="color: rgb(102, 102, 102);">?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">代理是通知目标对象后创建的对象。从客户端的角度看,代理对象和目标对象是一样的。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">60. </span><span style="color: rgb(102, 102, 102);">有几种不同类型的自动代理?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">BeanNameAutoProxyCreator</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">DefaultAdvisorAutoProxyCreator</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Metadata autoproxying</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">61. </span><span style="color: rgb(102, 102, 102);">什么是织入。什么是织入应用的不同点?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">织入是将切面和到其他应用类型或对象连接或创建一个被通知对象的过程。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">织入可以在编译时,加载时,或运行时完成。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">62. </span><span style="color: rgb(102, 102, 102);">解释基于</span><span style="color: rgb(102, 102, 102);">XML Schema</span><span style="color: rgb(102, 102, 102);">方式的切面实现。</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">在这种情况下,切面由常规类以及基于</span><span style="color: rgb(102, 102, 102);">XML</span><span style="color: rgb(102, 102, 102);">的配置实现。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">63. </span><span style="color: rgb(102, 102, 102);">解释基于注解的切面实现</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">在这种情况下</span><span style="color: rgb(102, 102, 102);">(</span><span style="color: rgb(102, 102, 102);">基于</span><span style="color: rgb(102, 102, 102);">@AspectJ</span><span style="color: rgb(102, 102, 102);">的实现</span><span style="color: rgb(102, 102, 102);">)</span><span style="color: rgb(102, 102, 102);">,涉及到的切面声明的风格与带有</span><span style="color: rgb(102, 102, 102);">java5</span><span style="color: rgb(102, 102, 102);">标注的普通</span><span style="color: rgb(102, 102, 102);">java</span><span style="color: rgb(102, 102, 102);">类一致。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">MVC</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">64. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">MVC</span><span style="color: rgb(102, 102, 102);">框架?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">配备构建</span><span style="color: rgb(102, 102, 102);">Web </span><span style="color: rgb(102, 102, 102);">应用的全功能</span><span style="color: rgb(102, 102, 102);">MVC</span><span style="color: rgb(102, 102, 102);">框架。</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">可以很便捷地和其他</span><span style="color: rgb(102, 102, 102);">MVC</span><span style="color: rgb(102, 102, 102);">框架集成,如</span><span style="color: rgb(102, 102, 102);">Struts</span><span style="color: rgb(102, 102, 102);">,</span><span style="color: rgb(102, 102, 102);">Spring </span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">MVC</span><span style="color: rgb(102, 102, 102);">框架用控制反转把业务对象和控制逻辑清晰地隔离。它也允许以声明的方式把请求参数和业务对象绑定。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">65. DispatcherServlet</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">的</span><span style="color: rgb(102, 102, 102);">MVC</span><span style="color: rgb(102, 102, 102);">框架是围绕</span><span style="color: rgb(102, 102, 102);">DispatcherServlet</span><span style="color: rgb(102, 102, 102);">来设计的,它用来处理所有的</span><span style="color: rgb(102, 102, 102);">HTTP</span><span style="color: rgb(102, 102, 102);">请求和响应。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">66. WebApplicationContext</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">WebApplicationContext </span><span style="color: rgb(102, 102, 102);">继承了</span><span style="color: rgb(102, 102, 102);">ApplicationContext  </span><span style="color: rgb(102, 102, 102);">并增加了一些</span><span style="color: rgb(102, 102, 102);">WEB</span><span style="color: rgb(102, 102, 102);">应用必备的特有功能,它不同于一般的</span><span style="color: rgb(102, 102, 102);">ApplicationContext </span><span style="color: rgb(102, 102, 102);">,因为它能处理主题,并找到被关联的</span><span style="color: rgb(102, 102, 102);">servlet</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">67. </span><span style="color: rgb(102, 102, 102);">什么是</span><span style="color: rgb(102, 102, 102);">Spring MVC</span><span style="color: rgb(102, 102, 102);">框架的控制器?</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">控制器提供一个访问应用程序的行为,此行为通常通过服务接口实现。控制器解析用户输入并将其转换为一个由视图呈现给用户的模型。</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">用一个非常抽象的方式实现了一个控制层,允许用户创建多种用途的控制器。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">68. @Controller </span><span style="color: rgb(102, 102, 102);">注解</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">该注解表明该类扮演控制器的角色,</span><span style="color: rgb(102, 102, 102);">Spring</span><span style="color: rgb(102, 102, 102);">不需要你继承任何其他控制器基类或引用</span><span style="color: rgb(102, 102, 102);">Servlet API</span><span style="color: rgb(102, 102, 102);">。</span></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><strong><span style="color: rgb(102, 102, 102);">69. @RequestMapping </span><span style="color: rgb(102, 102, 102);">注解</span></strong></p><p align="left" style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px;"><span style="color: rgb(102, 102, 102);">该注解是用来映射一个</span><span style="color: rgb(102, 102, 102);">URL</span><span style="color: rgb(102, 102, 102);">到一个类或一个特定的方处理法上。</span></p>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: