<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>klyuan</title>
    <description> 多年j2ee项目开发经验，现从事保险行业j2ee项目开发。熟悉struts,hibernate,ibatis,spring框架，有丰富的项目经验，擅系统分析及j2ee中小型项目架构设计</description>
    <link>http://klyuan.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title> 程序员为什么不写单元测试</title>
        <author>klyuan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://klyuan.javaeye.com">klyuan</a>&nbsp;
          链接：<a href="http://klyuan.javaeye.com/blog/97693" style="color:red;">http://klyuan.javaeye.com/blog/97693</a>&nbsp;
          发表时间: 2007年07月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div>&nbsp;程序员为什么不写单元测试</div>
<div><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>袁光东</div>
<div>&nbsp;</div>
<div>笔记曾经做过一次&ldquo;程序员在项目开发中编写单元测试的情况&rdquo;的调查。调查结果：</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>1.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>严格的在项目中执行TDD 几乎没有</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>2.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>为大部份业务方法编写单元测试，并保证方法测试通过。 占16.6%</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>3.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>偶尔编写单元测试，一般情况下不写。 占58.3%</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>4.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>为了应付项目检查而写单元测试，但并不保证方法是否测试通过。 占8.3%</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>5.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>从来不编写单元测试。占16.6%</div>
<div>因为调查具有一定的局限性或片面性，调查结果并不十分精确。也基本能够反映国内程序员编写单元测试的状况。很少有程序员能够比较认真的去编写单元测试。那么到底又是什么原因呢？根据笔者参与的多个讨论，主要有下面几种原因使程序员不编写单元测试。</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>1.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>为了完成编码任务，没有足够的时间编写单元测试。编写单元测试会导致不 能按时完成编码任务,推迟项目进度。</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>2.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>单元测试的价值不高，完全是浪费时间。</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>3.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>业务逻辑比较简单，不值得编写单元测试。</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>4.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>不知道怎么编写单元测试。</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>5.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>项目没有要求，所以不编写</div>
<div style="MARGIN: 0cm 0cm 0pt 18pt; TEXT-INDENT: -18pt"><span>6.<span style="FONT: 7pt 'Times New Roman'"><font size="3">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></span>在项目的前期还是尽量去编写单元测试，但是越到项目的后期，就越失控。</div>
<div>&nbsp;</div>
<div>测试常常是程序员十分厌倦的一个项目活动。测试能够为我们带来什么？了解这些非常的重要。测试不可能保证一个程序是完全正确的，但是测试却可以增强我们对程序的信心，测试可以让我们相信程序做了我们期望它做的事情。测试能够使我们尽量早的发现程序的bug.</div>
<div>一个bug被隐藏的时间的越长，修复这个bug的代价就越大。在《快速软件开发》一书中已引用了大量的研究数据。指出：最后才修改一个bug的代价是在bug产生时修改它的代价的10倍。</div>
<div>在这里，我们需要讨论的重点是单元测试。单元测试是一个方法层级上的测试，单元测试也是最细粒度的测试。用于测试一个类的每一个方法都已经满足了方法的功能要求。</div>
<div>在现代软件开发过程中，不管是xp还是rup都是十分重视单元测试。已经把单元测试作为贯穿整个开发周期的一项重要的开发活动。特别是在现代软件开发过程中，有经常集成和渐近提交的方法论。总结出了非常好的单元测试理论和实践:</div>
<div><span>&nbsp; </span>在编写代码之前先编写单元测试,即测试先行</div>
<div><span>&nbsp; </span>单元测试是代码的一部份，所有的代码必须有单元测试，并使测试通过。（像在Spring这些优秀的开源项目中在这方面做出了非常好的例子）</div>
<div><span>&nbsp; </span>在修改代码之前先修改单元测试，并使它测试通过。</div>
<div>&nbsp;</div>
<div>在编写代码之前先编写单元测试，会带来非常多的好处：</div>
<div><span>&nbsp; </span>在编写代码之前先编写单元测试，并不是编写代码之前需要一次性为所有的类都事先编写单元测试。这需要有一个粒度的把握。最大的粒度应该控制在一个类级别上，最合适的粒度是控制在一个方法级别上。先为某一个方法编写测试代码，然后再为该方法编写实现代码，直到其测试通过后再为另一个方法编写测试代码，如此循环。单元测试在这里已经是一个契约规范了，它规范了方法应该做什么，实现什么。测试代码远远要比难以阅读和不会及时更新的需求文档更有价值。</div>
<div><span>&nbsp;</span>测试先行，鼓励对需求的理解。如果没有理解需求，你是不可能写出测试代码的，当然你也不可能写出好的实现代码。</div>
<div><span>&nbsp; </span>测试代码与其它文档相比会更有价值。当需求发生改变，实现代码也相应改变。而往往需求文档，设计文档得不到及时更新。测试代码相比那些过期的文档更具有价值。</div>
<div><span>&nbsp; </span>测试先行可以编写出最大覆盖率的测试代码。如果在方法的实现代码编写完后再编写测试代码，这时开发人员总是编写一个正确路径的测试代码。它已经很难全面的去分析其它分支逻辑。</div>
<div><span>&nbsp; </span>如果我们采用测试先行，那么就自动的完成了为所有的类都编写测试这个实践原则。为所有的类都编写测试会将为你带来非常多的好处:</div>
<div>&nbsp;&nbsp;我们可以很好的使用自动化测试来测试所有的类，特别是采用日构建的系统。</div>
<div style="MARGIN: 0cm 0cm 0pt 15.75pt; TEXT-INDENT: -15.75pt"><span>&nbsp;&nbsp; </span>可以让我们放心的为类或方法添加新的功能。我们可以很容易的修改测试代码并验证修改后的代码是有用的代码。</div>
<div><span>&nbsp;&nbsp; </span>可以让我们放心的对代码进行重构和进行设计优化。重构和设计优化通常会关联到多个类及多个方法。如果我们为所有的类都编写了测试，我们就可以在重构代码后很轻松的进行测试我们的修改是否正确。</div>
<div><span>&nbsp;&nbsp; </span>为所有的类编写测试，可以让我们很容易的修改bug。当接到一个bug报告后，我们总是先修改测试代码，然后修改实现代码，使测试成功。这样不会因为修改一个问题而造成新问题的产生。</div>
<div>良好的单元测试策略给我们增强了对程序的信心,减少了bug的产生及bug的潜伏期。降低修改bug的代价。单元测试不会是项目开发周期的某一个生命周期，它贯穿于项目的整个生命周期，是一个非常重要的日常开发活动。</div>
<div>&nbsp;</div>
<div>我们已经知道了单元测试是多么重要的。为什么程序员仍然不编写单元测试呢？为什么程序员总是有理由拒绝编写单元测试呢？</div>
<div>一、编写单元测试，增加了工作负担，会延缓项目进度?</div>
<div><span>&nbsp;&nbsp; </span>这是笔者在多次讨论和调查中程序员拒绝编写单元测试的最多理由。&ldquo;为了完成编码任务，没有足够的时间编写单元测试。编写单元测试会导致不能按时完成编码任务,推迟项目进度&rdquo;。事实上真的是这样的吗？软件有着其特殊的生命周期，软件开发也具有特殊性。</div>
<div>首先，我们需要提供给用户的至少是一个能运行的产品。绝对不能是一堆不能运行的和充满了异味的哑代码。只有能够运行的，满足客户需求的代码才是真正有用的代码。这时代码就变成产品了。<br />
很多程序员只关注编写代码的完成时间，而乎略了调试代码，集成及修改和维护时间。</div>
<div>如果没有单元测试，开发活动会是这样的情景。</div>
<div>以一个web应用开发为例：业务代码编写完成<span>-&gt;</span>打包-&gt;发布到服务器-&gt;进行功能测试<span>-&gt;</span>发现问题<span>-&gt;</span>修改代码<span>-&gt;</span>再打包&hellip;&hellip;如此循环。</div>
<div>任何一个web程序员对于这种开发情景都不会感到陌生。往往不断的打包，发布，功能测试的时间是代码编写的10倍以上。通过集成系统来发现程序的bug，我们往往很难一下子准确的定位bug产生的地方。应用服务器提供的错误信息对于我们来说是非常有限的。</div>
<div>如果为每一个类都编写单元测试并让每一个方法测试通过，又会是怎么样的开发情景呢？</div>
<div style="TEXT-INDENT: 5.25pt">编写测试代码<span>-&gt;</span>编写业务代码-&gt;运行测试方法-&gt;修改代码让测试通过-&gt;所有的类都通过测试-&gt;打包-&gt;发布到服务器-&gt;进行功能测试<span>-&gt;</span>发现bug-&gt;修改测试代码-&gt;修改业务代码-&gt;测试通过-&gt;再打包&hellip;如此循环。</div>
<div style="TEXT-INDENT: 5.25pt">从上面的过程显而易见，我们需要花费更多的编码时间。因为需要为每一个业务类编写测试代码。但是它并不会导致我们总体需要花费更多的时间。我们只是可以非常轻松的在ide环境中运行测试方法。在代码尚未打包发布之前我们就已经确保了业务代码的正确性。当我们把所有通过测试的代码集成到应用服务器后，出现错误的机率要少得多。当集成测试后发现bug时,我们也总是先修改测试类。保证在集成之前所有的类都经过测试通过。这样功能测试的时间就成数量级的减少,所以总的花费时间要比没有单元测试要少得多。</div>
<div style="TEXT-INDENT: 5.25pt"><span>&nbsp;</span>另外，如果没有单元测试，会经常出现一些低级的错误，如拼写错误，空指针异常等。就因为一个小小的拼写错误而需要重新打包，发布一次。如果有单元测试，就可以避免这些低级的错误。</div>
<div style="TEXT-INDENT: 5.25pt">如果没有单元测试，把代码集成到应用服务器后再发现错误时，我们往往更多的是凭借自己的经验来判断问题出在哪里。对于没有经验的程序员来说只能是撞运气了。这就像是瞎子走路一样，两眼一把黑。如果每个类都有单元测试，就无需要这么痛苦了。</div>
<div style="TEXT-INDENT: 5.25pt">这使得我回想起当年做网络系统。当时的局域网络都是采用环状网络，还没有现在的交换机来组星形网络。环状网络的传输网络采用同轴细缆线，网络中的所有节点都在一条主干线上，网络的两端都会加上一个电阻来形成一个环。</div>
<div style="TEXT-INDENT: 5.25pt">环状网络的最大的缺点就是当任意一个节点有固障时，整个网络都不能连通。维护这种网络是非常麻烦的。通常采用得比较多的方法就是&ldquo;切香肠&rdquo;法。把最后一个电阻取下来，接到第二台电脑的网络节点的末端，检查两条线是否能连通。连通后再把电阻取下来到第三台电脑的网络节点的末端，连上第三台电脑。这样来依次检查整个网络的线路。</div>
<div style="TEXT-INDENT: 5.25pt">后来发展了星形网络，也是现在局域网普遍采用的。有一台交换机，每一台电脑连接到交换机，任意一个节点网络故障不会影响到其它节点，检查起来就非常方便了。没有单元测试的代码就像是环状网络，而有测试的代码就像星形网络。</div>
<div style="TEXT-INDENT: 5.25pt"><span>&nbsp;</span>其次，有可能我们第一次编写的代码是没有问题的，但是到后来需求改变而修改了其中某些类的代码，把它发布到了应用服务器去测试，所要修改的内容已经测试通过了。但是因为某些类的修改导致了其它类不能正常的工作。这种bug往往隐藏得非常深，因为只要不触动它，它就不会出现。可能会程序发布到生产环境之后才会被业务人员发现。如果每个类都有测试代码，我们在打包之前运行所有测试代码，就可以很容易的发现因为代码修改带来的连带性错误。</div>
<div style="TEXT-INDENT: 5.25pt"><span>&nbsp;</span>其三，在离bug产生越近，修正bug就越容易；在bug产生越远，修正bug的代价就越昂贵。假设我们去集成一个星期(甚至更长时间)前编写的代码，当发现问题时，我们已经忘掉了很多重要的实现细节,所以修改变得困难重重。</div>
<div style="TEXT-INDENT: 5.25pt">编写单元测试，并不会加重程序员的负担，反而提高了程序员对程序的信心，大大的减少了重复打包，发布，纠错误的时间。这些花费的时间远远要比编写单元测试花费的时间多几个数量级。编写单元测试，可以让你更容易和更放心的去修改代码，增加功能从而加快了项目的开发进度。</div>
<div style="TEXT-INDENT: 5.25pt">为什么我们总是要主观的去认为编写单元测试会延缓项目进度呢？与其痛苦的挣扎，还不如去尝试一下好的实践。</div>
<div style="TEXT-INDENT: 5.25pt">&nbsp;</div>
<div style="TEXT-INDENT: 5.25pt">二、业务逻辑简单，不值得编写单元测试</div>
<div style="TEXT-INDENT: 5.25pt"><span>&nbsp; </span>程序员是聪明的，程序员也总是自认为是聪明的。认为一些业务逻辑比较简单的类不必要编写单元测试。我们必须承认，需求不断变化，我们也必须要有勇气去接受需求变化。编写单元测试的另一个目的就是拥抱变化，而不是拒绝变化。编写单元测试就是提高了我们对程序的信心。在敏捷软件开发中，代码为集体所有，项目组的任何一个人都可以去修改任何一个代码文件。每当我要去修改一个别人编写的代码时，我总是多么的希望有程序的单元测试代码，而往往都让我非常的失望。一般我都得花费很大的力气去猜想原作者的原始意图。也许你会说：&ldquo;你可以去看需求文档啊！你不会去看注释吗？&rdquo;。但实际情况是，当需求文档完成了它的使命后，开发人员就把它扔到了一边了，文档总是过期的。没有几个项目组能够使得需求，设计这些文档与最新实现代码保持一致。所以去看一个过期的文档是没有价值的。注释也同样，保持最新仍然是一个最大的问题，并且注释能够提供的信息是非常有限的。所以我最需要的就是看测试代码了。测试代码最能反映出方法最新的功能契约。由代码的编写者去写的单元测试要比由其它人去编写的单元测试要更完善,更准确。</div>
<div style="TEXT-INDENT: 5.25pt">很多问题恰恰就出在一些我们认为简单的代码中。除非是像一个JavaBean的getter和setter方法，因为这些方法可以通过IDE自动代码生成，没有必要为它编写测试。</div>
<div style="TEXT-INDENT: 5.25pt">在项目开发中，我们需要经常通过重构来优化代码及改进我们的设计,当我们对代码进行重构之后，怎么能够保证代码仍然是正确的？那就是运行所有被修改的代码的测试。如果测试通过，则说明我们的重构是正确。</div>
<div style="TEXT-INDENT: 5.25pt">我们不能回避代码的维护问题。代码维护包括修正bug和增加功能。维护工作可能会距离代码编写完成有很长一段时间。当需要修改一个bug而修改了代码，或增加一个新的功能而修改了代码时，又怎么能够保证修改后的代码仍然是正确的和没有隐患的呢？也许你会说，发布到应该服务器去测试就知道了。笔者曾经发生过因为维护而导致了更严重问题发生的情况。一个系统在生产环境正常运行很长时间了。某一天，业务人员要求修改某一个功能,笔者按业务的要求实现了要修改的功能，业务也测试了修改后的功能，然后发布到了生产环境。程序下发两个星期后，报了一个非常严重的生产问题上来，以前能够正常运行的功能突然有问题了，导致了大量的生产数据错误。这个问题是非常致命的，只能暂时停用系统。</div>
<div style="TEXT-INDENT: 5.25pt">最后我查明原因是，出错的模块与上次修改的代码有关联，上次修改时没有同时去修改现在出错的模块。要是我能够在修改代码后，运行所有的测试类，测试就肯定会报告不通过。也就不会把隐藏有这么严重错误的程序下发到生产环境去。</div>
<div><span>&nbsp; </span>我们看看没有写单元测试是怎么进行集成的。如果某些结果与我们所期望的不一致时，我们可能会在程序中加上许多print语句，然后通过控制台来监视程序的运行过程。采用print语句并不能够保证我们的程序的正确性。最好的情况是，它只能保证一条正确的路径，不能保证其它的分支。另外当太多的print语句的信息在控制台上，也会让我们看不到想看到的信息，控制台的信息是有限的。在开发测试时，把调试信息打印在控制台还可以接受，但是在生产环境，如果还有调试信息出现在控制台，那是绝对不可以接受的。我们经常会忘记把调试的print语句及时的删除掉，从而影响程序的性能。最关键的是，print语句不能保证程序的正确性，也不能为你节省开发的时间。只会给你带来负面的影响。</div>
<div>&nbsp;</div>
<div>三、不知道怎么编写单元测试</div>
<div><span>&nbsp; </span>如果你相信单元测试的价值，那么去学习如何编写单元测试最终会让你获益的。</div>
<div>以java开发为例，junit这样的单元测试组件是非常易于学习和使用的。其它语言也有类似的单元测试组件。要相信这将是简单和能为你带来价值的。但是笔者见过许多程序员编写的单元测试完全没有起到它应有的作用。这也与不知道怎么编写单元测试有关。所以我们应该掌握一些编写单元测试的基本原则:</div>
<div><span>&nbsp; </span>应该为什么编写测试：虽然我们说为所有的代类都编写单元测试，但是测试JavaBean的setter或getter方法无异于是自寻烦恼。编写这样的测试完全是浪费时间。而且还增加了维护的困难。</div>
<div><span>&nbsp; </span>学会使用断言：断言就是让我们为方法设置一个期望值。当方法执行结果与期望值不一致时，测试组件就会报告测试不通过。我见过一些项目的单元测试不是使用断言，而是自己编写一个打印(println)工具类，可以详细的在控制台中打印出类的详细成员信息，及集合的详细信息。在单元测试中使用这个打印工具类来打印输出结果。这看起来好像非常不错。但是不应该使用这种方式来编写单元测试</div>
<div>使用打印工具类，需要程序员自已从控制台去观察程序的执行结果。当输出信息非常多时，控制台信息是无法向上翻屏的。所以不能够给我们提供更多的信息。所以这种方法也不能用于自动化测试。</div>
<div>使用打印工具类，造成了一种假像，测试报告我们的测试总是成功的！如果使用断言，当方法的执行结果与我们设置的期望值不一致时，则会详细的报告测试失败的情况。</div>
<div>使用打印工具来代替断言，造成测试的不充分，只会写出一个低测试覆盖率的测试。我们需要一个充分的测试。</div>
<div><span>&nbsp; </span>最大化测试覆盖率：我们除了测试一个正确的路径外，我们还需要测试方法的每一个分支逻辑。需要编写尽可能多的测试程序逻辑的测试。写一个充分的测试。</div>
<div><span>&nbsp; </span>避免重复的测试代码：测试类也是非常重要的，与应用代码一样。测试类包含的重复代码越多，测试类自身出现的错误也会越多。而我们需要做的编码工作也就越多。</div>
<div><span>&nbsp; </span>不要依赖于测试方法的执行顺序：使用Junit来进行单元测试，它不能保证测试方法按照我们的意图的顺序来执行。当一个测试类有多个测试方法时，我们不能让一个测试方法必须在某一个测试之后执行才能成功。Junit不能为我们做这样的保证，我们不能依赖于测试方法的执行顺序。</div>
<div><span>&nbsp; </span>针对接口测试：我们有&ldquo;针对接口编程&rdquo;的oo设计原则。同样对于测试，我们也需要针对接口测试。也就是说在编写单元测试时，测试对象总是使用接口，而不是使用具体类。</div>
<div>&nbsp;</div>
<div>四、项目没有要求，所以不编写</div>
<div><span>&nbsp; </span>的确在很多项目中，团队并没有要求程序员为每一个类编写单元测试。反而会要求我们编写很多复杂的文档。作为程序员我们需要明白：程序员是编写单元测试的最大受益者。</div>
<div>这不是项目经理的事，也不是QA的事，而是程序员自身的事。因为单元测试是程序代码的一部份。单元测试是最好的，最有价值的文档，它应该与代码一起交付给客户。</div>
<div><span>&nbsp;&nbsp; </span>单元测试代码不是官僚，死板的文档。它是生动的，是程序员最有用的文档。单元测试能够提高程序员对程序的信心，能够使用养成良好的设计原则：&ldquo;针对接口编程，而不是具体类&rdquo;。因为要进行单元测试，所以我们需要让类独立于其依赖对象(使用Mock或stub)进行测试。这就迫使我们养成了良好的编程习惯。</div>
<div><span>&nbsp; </span>单元测试是改进我们设计的保证。做为一个优秀的程序员，是会经常优化代码和设计，所以经常的进行重构。一个优秀的程序员绝对不能容忍异味代码。而单元测试就是我们进行重构的信心保证。</div>
<div><span>&nbsp; </span>单元测试是一个日常开发活动，它贯穿于项目的整个生命周期。做一个负责任的程序员总是为自己的代码的质量负责的。是否经常改进你的设计，是否让别人很轻松的使用和修改你的代码。</div>
<div>为所有类编写单元测试应该是一个程序员应具有的素质。项目有没有要求，不应当成为不编写单元测试的理由。</div>
<div>五、为什么越在项目的后期，单元测试就越难以进行下去？</div>
<div><span>&nbsp; </span>在很多项目的初期，项目中的大部分程序员都能够自觉的去编写单元测试。随着项目的进展，任务的加重，离交付时间越来越近，不能按时完成项目的风险越来越大，单元测试就往往成为牺牲品了。项目经理因为进度的压力也不重视了，程序员也因为编码的压力和无人看官而不再为代码编写单元测试了。</div>
<div><span>&nbsp; </span>笔者所有亲历的项目都着像这么糟糕的情况发生。越是在项目的后期，能坚持编写单元测试的程序就在整个项目组中不会超过15%。为了追赶进度，绝大多数程序员都把没有经过任何测试的代码提交到版本服务器,项目经理也不再追问，照单全收。这样做的结果就是在后期，集成花费的时间越来越多，几个技术骨干人员只得日夜加班进行系统集成。好不容易集成完了之后，下发给测试人员测试时，bug的报告成数量级的增长。程序员就日以继夜的修改bug.还有非常多的bug被隐藏更深，一直潜伏到生产环境去。项目中，越来越多的人对项目失去信心，每一个人都在抱怨，数不清的bug,修正了一个bug,更多的bug报告上来。</div>
<div>每天都在修改bug,但是每天又会报告上更多的bug。于是开始有人想逃离了，有人请假，也有人离职。当项目总算结束时，每一个的内心都清楚，项目太烂了，还有很多的错误还没被测试出来，赶快逃离这个项目组吧！一半的人病倒了，或对项目的维护失去了信心。</div>
<div>为什么会这样？有没有宣导测试的重要性呢？</div>
<div>在项目初期应该进行宣导单元测试的重要性。</div>
<div>有没有做过相关的培训工作？在项目启动时，需要进行一些相关的培训，教授团队成员最基本的编写单元测试的技巧。</div>
<div>有没有做过相应的风险防范？越是工作资历越深的程序员，就越会拒绝编写单元测试，他们总是有太多的理由来拒绝编写单元测试。这些顽固的老程序员往往负责着核心的代码的编写。我们知道20-80定律吧。80%的错误是发生在20%的代码之中的，往往最严重的错误就发生在那些老鸟们的代码中。有没有在事先就做好风险防范，说服他们编写单元测试。</div>
<div>有没有做好测试相关的基础工作。有没有针对不同类型的程序编写测试基类，让编写测试变成一项非常简单的工作。有一些代码是依赖于特定的环境，如EJB访问，JNDI访问，web应用程序依赖Servlet API等。测试这些程序是非常困难的。应该编写一些测试基类和测试stub，让这些程序可以脱离于特定环境就像普通程序一样进行单元测试。让普通程序员轻松的编写测试代码进行程序测试。</div>
<div>可以实行日构建和测试覆盖率检查，没有通过测试的代码绝不允许放到版本服务器。检查测试的覆盖率。</div>
<div>&nbsp;</div>
<div><span>&nbsp; </span>在现代软件开发过程中，测试不再作为一个独立的生命周期。单元测试成为与编写代码同步进行的开发活动。单元测试能够提高程序员对程序的信心，保证程序的质量，加快软件开发速度，使程序易于维护。不管测试先行还是测试后行，没有单元测试那是绝对不行的。</div>
<div><span>&nbsp; </span>弱者为失败找理由，强者为成功找方法！今天你单元测试了吗？</div>
          <br/>
          <span style="color:red;">
            <a href="http://klyuan.javaeye.com/blog/97693#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 04 Jul 2007 11:31:57 +0800</pubDate>
        <link>http://klyuan.javaeye.com/blog/97693</link>
        <guid>http://klyuan.javaeye.com/blog/97693</guid>
      </item>
      <item>
        <title>Spring JavaConfig开发指南(下)</title>
        <author>klyuan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://klyuan.javaeye.com">klyuan</a>&nbsp;
          链接：<a href="http://klyuan.javaeye.com/blog/86273" style="color:red;">http://klyuan.javaeye.com/blog/86273</a>&nbsp;
          发表时间: 2007年06月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div style="MARGIN: 0cm 0cm 0pt 39pt">
<table cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse">
    <tbody>
        <tr style="HEIGHT: 37.7pt">
            <td valign="top" width="135" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 101.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div><code><strong>lazy</strong></code></div>
            </td>
            <td valign="top" width="121" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>Lazy</div>
            </td>
            <td valign="top" width="97" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>延时初始化策略</div>
            </td>
            <td valign="top" width="125" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>UNSPECIFIED</div>
            </td>
            <td valign="top" width="69" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr style="HEIGHT: 37.7pt">
            <td valign="top" width="135" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 101.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div><code><strong>meta</strong></code></div>
            </td>
            <td valign="top" width="121" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>Meta[]</div>
            </td>
            <td valign="top" width="97" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>当前<span>bean的元数据</span></div>
            </td>
            <td valign="top" width="125" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>{}</div>
            </td>
            <td valign="top" width="69" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr style="HEIGHT: 37.7pt">
            <td valign="top" width="135" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 101.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div><code><strong>scope</strong></code></div>
            </td>
            <td valign="top" width="121" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>String</div>
            </td>
            <td valign="top" width="97" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.85pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>Bean的作用域</div>
            </td>
            <td valign="top" width="125" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>singleton</div>
            </td>
            <td valign="top" width="69" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 37.7pt; BACKGROUND-COLOR: transparent">
            <div>Singleton,prototype或自定义作用域</div>
            </td>
        </tr>
    </tbody>
</table>
</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">使用纯java方式的bean定义时，处理静态方法时，不再需要-Factory-method</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;ExampleBean&nbsp;exampleBean()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;</span><span class="keyword">return</span><span>&nbsp;ExampleFactory.createBean(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">当用方法来定义一个Bean时，这个方法必须是public的。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">示例：使用aliases元素。,定义一个Bean，别名为hello</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="annotation">@Bean</span><span>(aliases={</span><span class="string">&quot;hello&quot;</span><span>}) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;HelloWorld&nbsp;helloWorld(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>HelloWorld&nbsp;helloWorld&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;HelloWorld(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>helloWorld.setWord(word()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;helloWorld; &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(ConfigurationFull.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>HelloWorld&nbsp;hello&nbsp;=&nbsp;(HelloWorld)context.getBean(</span><span class="string">&quot;hello&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>hello.sayHello(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt"><strong><span style="FONT-SIZE: 12pt">1.1&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">@ExternalBean</span></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">指定<span>Bean是一个外部Bean</span></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;示例<span>:</span></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="annotation">@Configuration</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ExternalConfiguration&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="annotation">@ExternalBean</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">abstract</span><span>&nbsp;HelloWorld&nbsp;helloWorld(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConfigurationWithExternal&nbsp;{ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(ConfigurationFull.</span><span class="keyword">class</span><span>.getName(),ExternalConfiguration.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;HelloWorld&nbsp;hello&nbsp;=&nbsp;(HelloWorld)context.getBean(</span><span class="string">&quot;helloWorld&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;hello.sayHello(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">这里，在ExternalConfiguration中定义的helloWorld自动会被,在ConfigurationFull中定义的helloWorld覆盖。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">所以，@ExtenalBean的意思是，这个是在父Context中定义的,这个父context可以是一个Configuration或是一个外部的xml文件。使用这个注释的好处是为了保持重构友好。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt"><strong><span style="FONT-SIZE: 12pt">1.2&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">@ScopedProxy</span></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">Spring通过<span>scoped proxies提供了一个方便的作用域依赖的处理方法。最简单的方式就是创建一个代理。在当使用xml配置时，使用<aop:scoped-proxies></aop:scoped-proxies>元素。JavaConfig提供了一个等价物就是@ScopedProxy,它提供了<aop:scoped-proxies></aop:scoped-proxies>相同的语义和配置选项。</span></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="annotation">@Bean</span><span>(scope&nbsp;=&nbsp;DefaultScopes.SESSION) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="annotation">@ScopedProxy</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;UserPreferences&nbsp;userPreferences()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;</span><span class="keyword">new</span><span>&nbsp;UserPreferences(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;Service&nbsp;userService()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;UserService&nbsp;service&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;SimpleUserService(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="comment">//&nbsp;a&nbsp;reference&nbsp;to&nbsp;the&nbsp;proxied&nbsp;'userPreferences'&nbsp;bean </span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;service.seUserPreferences(userPreferences()); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;service; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
一个<span>userPreferences的Bean定义了Session的作用域，一个为singleton作用域的Bean userService注入了这个bean userPreferences.因为userSerivce只会被实例化一次，理论上它只会操纵一个userPreferences对象。而我们是希望它每次去从session中取回一个userPreferences对象。所以这就需要一个代理。这个代理总会在我们需要使用userPreferences对象时，自动去从session中取回userPreferences对象。</span></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt"><aop:scoped-proxies></aop:scoped-proxies>及<span>@ScopedProxy就是提供了这样的功能。</span></div>
<div>&nbsp;</div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">2.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Bean的可见度</font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">&nbsp;&nbsp;&nbsp;&nbsp; JavaConfig</span><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">有一个非常好的特性就是可以控制Bean的可见度。JavaConfig可以使用Java方法的可见度修饰符来决定Bean是否可以被Application Context 和Bean Factory访问</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="annotation">@Configuration</span><span>&nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;VisibilityConfiguration&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;</span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;UserInfo&nbsp;publicUserInfo(){ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserInfo&nbsp;user&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;UserInfo(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setName(protectedName()); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.setAddres(privateAddres()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;user; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;</span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;</span><span class="keyword">protected</span><span>&nbsp;String&nbsp;protectedName(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name&nbsp;=&nbsp;</span><span class="string">&quot;jack&quot;</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;name; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;privateAddres(){ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;addres=&nbsp;</span><span class="string">&quot;Beijing&quot;</span><span>; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;addres; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
上面三个由方法定义的Bean中，方法分别为public ,protected,private。</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConfigurationWithVisibility&nbsp;{ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(VisibilityConfiguration.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserInfo&nbsp;user&nbsp;=&nbsp;(UserInfo)context.getBean(</span><span class="string">&quot;publicUserInfo&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;protectedName&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;addres&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;privateAddres&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5">&nbsp;</font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">当我们在Context中访问&quot;protectedName&quot;或&quot;privateAddres&quot;时都会抛出异常</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'protectedName' is defined</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5">&nbsp;</font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">但是在VisibilityConfiguration内部，三个Bean是相互可以访问的。</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">所以如果在用@Bean注释的方法，如果不是public的，是不能被外部的ApplicationContext访问的。</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5"><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">JavaConfig </span><span style="FONT-WEIGHT: normal; FONT-SIZE: 10.5pt">提供了Bean的可见度功能，利用Spring提供的层级应用上下文，用一个特殊的Configuration类来放置所有的隐藏Bean,在一个子应用上下文内，隐藏Bean能够访问父应用上下文定义的Bean。而父应用上下文的Bean却不能访问子应用上下文的隐藏Bean.</span></font></strong></div>
<div style="MARGIN: auto 0cm"><strong><font size="5">&nbsp;</font></strong></div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5"><span style="FONT-WEIGHT: normal">3.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span>Bean的依赖设置</font></strong></div>
<div>装配一个<span>Bean，最简单的方法就是java提供的构造函数</span></div>
<div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="annotation">@Bean</span><span>(scope=DefaultScopes.PROTOTYPE) &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;UserInfo&nbsp;userInfo(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;UserInfo&nbsp;user&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;UserInfo(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;user.setName(name()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;user; &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="annotation">@Bean</span><span>(scope=DefaultScopes.SINGLETON) &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;String&nbsp;name(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name&nbsp;=&nbsp;</span><span class="string">&quot;jack&quot;</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span class="keyword">return</span><span>&nbsp;name; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div>Bean之间依赖的设置通过<span>bean的方法名来进行设置，并不是通过bean名称。</span></div>
<div>Name()方法被<span>@Bean注释后，它的Bean名称是name,但是在userInfo方法，来设置name属性是仍然需要使用方法名name(),而不是bean名称name.</span></div>
<div>&nbsp;</div>
<div>
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>当使用</span><span class="annotation">@Bean</span><span>标记后，Bean都会由Spring容器进行管理。UserInfo声明为prototype,而name声明为singleton. &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(VisibilityConfiguration.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserInfo&nbsp;user&nbsp;=&nbsp;(UserInfo)context.getBean(</span><span class="string">&quot;userInfo&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserInfo&nbsp;user2&nbsp;=(UserInfo)context.getBean(</span><span class="string">&quot;userInfo&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(user&nbsp;==&nbsp;user2); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;name&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;name2&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;name&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(name&nbsp;==&nbsp;name2); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span> </li>
</ol>
</div>
输出结果：</div>
<div align="left"><span style="FONT-SIZE: 10pt; COLOR: black">false</span></div>
<div><span style="FONT-SIZE: 10pt; COLOR: black">true</span></div>
<div>&nbsp;</div>
<div>可见，被<span>@Bean标记后</span>，每次从<span>ApplicationContext中获得的userInfo的对象都不是同一个对象。而每次获得的name的对象都是同一个对象。</span></div>
<div style="MARGIN: auto 0cm"><strong><font size="5">&nbsp;</font></strong></div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">4.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>使用<span>JavaConfig</span></font></strong></div>
<div><span>&nbsp;&nbsp; </span>我们在前面的例子，已经多次看到了<span>AnnotationApplicationContext的使用。现在来全面介绍AnnotationApplicationContext.</span></div>
<div>AnnotationApplicationContext提供了四个构造函数。</div>
<div>1.public AnnotationApplicationContext(java.lang.Class... classes)</div>
<div>可以把多个<span>Configuration类构造成一个ApplicationContext</span></div>
<div>2. public AnnotationApplicationContext(java.lang.String... locations)</div>
<div>&nbsp;除了可以接收多个完整的<span>Configuration类构造成一个ApplicationContext外，还可以接改ant风格的类路径。</span></div>
<div>&nbsp;例如：<span>ApplicationContext context = new AnnotationApplicationContext(ConfigurationFull.class.getName(),ExternalConfiguration.class.getName());</span></div>
<div>&nbsp;</div>
<div>ApplicationContext context = new AnnotationApplicationContext(&quot;**/configuration/*Configuration.class&quot;);</div>
<div>&nbsp;</div>
<div>3.public &nbsp;AnnotationApplicationContext(org.springframework.context.ApplicationContext parent)</div>
<div>给定一个父<span>ApplicationContext来构造一个AnnotationApplicationContext.</span></div>
<div>&nbsp;</div>
<div>4. public AnnotationApplicationContext()</div>
<div>一个默认的构造函数</div>
<div>&nbsp;</div>
<div>上面这些都是针对<span>Configuration类的。而我们更多的时候需要与xml结合进行使用。</span></div>
<div>这就需要使用到org.springframework.config.java.process.ConfigurationPostProcessor.</div>
<div class="code_title">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span><!--l version=</sp--><span class="string">&quot;1.0&quot;</span><span>&nbsp;encoding=</span><span class="string">&quot;UTF-8&quot;</span><span>?&gt; &nbsp;&nbsp;</span></span> </span></li>
    <li class=""><span><!--CTYPE beans PUBLIC </sp--><span class="string">&quot;-//SPRING//DTD&nbsp;BEAN&nbsp;2.0//EN&quot;</span><span>&nbsp;</span><span class="string">&quot;http://www.springframework.org/dtd/spring-beans-2.0.dtd&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span><beans></beans>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="keyword">class</span><span>=</span><span class="string">&quot;com.springconfig.example.chapter3.ConfigurationFull&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;<span class="keyword">class</span><span>=</span><span class="string">&quot;org.springframework.config.java.process.ConfigurationPostProcessor&quot;</span><span>/&gt;&nbsp;&nbsp; &nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<div class="code_title"></div>
<div class="code_title">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ClassPathXmlApplicationContext(</span><span class="string">&quot;com/springconfig/example/chapter3/applicationContext.xml&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;word&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;word&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(word); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<div>程序运行结果</div>
<div><span style="FONT-SIZE: 10pt; COLOR: black">HelloWorld!</span></div>
<div>&nbsp;</div>
<div>注意，外部的<span>xml可以直接使用Configuration中配置的Bean,而Configuration中的Bean需要使用Xml中的Bean，则需要使用@External注释。</span></div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div>&nbsp;</div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">5.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Bean的命名策略</font></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">使用JavaConfig由方法产生的Bean,其方法名就是Bean名称。但是当多个方法重名，或者有多个Congiguration或与外部xml混用时，这种方式并不合适。不同的类全覆盖彼此的定义。为了自定义bean名称产生的行为，可以能过实现<tt><span style="FONT-SIZE: 12pt">BeanNamingStrategy</span></tt> 接口来提供它自己的bean名称产生策略</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">BenaNamingStrategy有一个默认的实现<tt><span style="FONT-SIZE: 12pt">MethodNameStrategy</span></tt></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">MethodNameStrategy提供了一个prefix属性，用于指定Bean的前辍的产生方式</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">Prefix有三个取值。</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">NONE:即没有前辍，仍然使用方法名作为Bean的名称。</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">CLASS：使用类名称为作Bean的前辍，中间以.号相连。如：ConfigurationFull.word</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">FQN:使用完整的类路径作为Bean的前辍。如：com.springconfig.example.chapter3.ConfigurationFull.word</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">下面就这三种方式进行说明：</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span><!--l version=</sp--><span class="string">&quot;1.0&quot;</span><span>&nbsp;encoding=</span><span class="string">&quot;UTF-8&quot;</span><span>?&gt; &nbsp;&nbsp;</span></span> </span></li>
    <li class=""><span><!--CTYPE beans PUBLIC </sp--><span class="string">&quot;-//SPRING//DTD&nbsp;BEAN&nbsp;2.0//EN&quot;</span><span>&nbsp;</span><span class="string">&quot;http://www.springframework.org/dtd/spring-beans-2.0.dtd&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span><beans></beans>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">class</span><span>=</span><span class="string">&quot;com.springconfig.example.chapter3.ConfigurationFull&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="keyword">class</span><span>=</span><span class="string">&quot;org.springframework.config.java.process.ConfigurationPostProcessor&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;namingStrategy&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">class</span><span>=</span><span class="string">&quot;org.springframework.config.java.naming.MethodNameStrategy&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;prefix&quot;</span><span>&nbsp;value=</span><span class="string">&quot;CLASS&quot;</span><span>/&gt; &nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt"></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ClassPathXmlApplicationContext(</span><span class="string">&quot;com/springconfig/example/chapter3/applicationContext.xml&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;word&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;ConfigurationFull.word&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(word); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">程序输出：</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-SIZE: 10pt; COLOR: black">HelloWorld!</span></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-SIZE: 10pt; COLOR: black">把上面的</span><span style="FONT-SIZE: 10pt; COLOR: black">prefix</span><span style="FONT-SIZE: 10pt; COLOR: black">属性值换成</span><span style="FONT-SIZE: 10pt; COLOR: black">FQN</span></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt"></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;ClassPathXmlApplicationContext(</span><span class="string">&quot;com/springconfig/example/chapter3/applicationContext.xml&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;String&nbsp;word&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;com.springconfig.example.chapter3.ConfigurationFull.word&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(word); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">程序输出：</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt"><span style="FONT-SIZE: 10pt; COLOR: black">HelloWorld!</span></div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">6.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>注释还是<span>XML</span></font></strong></div>
<div>&nbsp;Spring因为XML大量使用而受到了越来越多的批评，也使得基于Spring的项目变得越来越复杂。使用XML来配置Bean,它无法进行类型安全检查，当类名称或方法名被改名之后，XML中的相应配置无法随之改变。这对项目的重构带来了极大的不方便。随着JAVA EE 5,JAVA EE 6的相继推出，其中一个最大的特性就是注释的使用。当Spring使用注释来Bean时，就可以在一个纯java的类中配置Bean.因为是在纯java的环境中，可以获得编译期类型安全检查的好处,当Bean的类名或方法名进行重构修改后，Configuration中的相应的定义会被同时修改。</div>
<div>&nbsp;JavaConfig就是为了简化Spring项目的产生的，JavaConfig的使用也非常的简单，可见JavaConfig应该是简化Spring项目的一种最好解决方式。但是并不意味着，JavaConfig就应该完全的取代xml配置。Xml的优势是就是配置的灵活性和参数化以及访问外部环境，以及在web系统中的应用。JavaConfig并不排斥xml，相反，它可以和xml很好的相结合，来降低spring项目开发的复杂度。在未来，xml应该会成为JavaConfig的补充。</div>
<div>&nbsp;</div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">7.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>关于文档</font></strong></div>
<div><span>&nbsp; </span>该文档是一个全免费的文档，可以免费传播。引用请获得作者的同意！</div>
          <br/>
          <span style="color:red;">
            <a href="http://klyuan.javaeye.com/blog/86273#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 03 Jun 2007 10:56:47 +0800</pubDate>
        <link>http://klyuan.javaeye.com/blog/86273</link>
        <guid>http://klyuan.javaeye.com/blog/86273</guid>
      </item>
      <item>
        <title>Spring JavaConfig开发指南(上)</title>
        <author>klyuan</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://klyuan.javaeye.com">klyuan</a>&nbsp;
          链接：<a href="http://klyuan.javaeye.com/blog/86267" style="color:red;">http://klyuan.javaeye.com/blog/86267</a>&nbsp;
          发表时间: 2007年06月03日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div style="MARGIN: 17pt 0cm 16.5pt"><strong><font size="6">Spring JavaConfig开发指南</font></strong></div>
<div>作者：袁光东</div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">1.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>什么是<span>JavaConfig</span></font></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">Spring IOC有一个非常核心的概念&mdash;&mdash;Bean。由Spring容器来负责对Bean的实例化，装配和管理。XML是用来描述Bean最为流行的配置方式。Spring可以从XML配置文件中读取任何类型的元数据并自动转换成相应的Java代码。Spring开变了java的编程模式，Spring的下载已经超过了1亿次,可见Spring已经有多流行。</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">随着Spring的日益发展，越来越多的人对Spring提出了批评。&ldquo;Spring项目大量的烂用XML&rdquo;就是最为严励的一个批评。由于Spring会把几乎所有的业务类都以Bean的形式配置在XML文件中，造成了大量的XML文件。使用XML来配置Bean失去了编译时的类型安全检查。大量的XML配置使得整个项目变得更加复杂。Rod Johnson也注意到了这个非常严重的问题。当随着JAVA EE 5.0的发布，其中引入了一个非常重要的特性------Annotations(注释)。注释是源代码的标签，这些标签可以在源代码层进行处理或通过编译器把它熔入到class文件中。在JAVA EE 5以后的版本中，注释成为了一个主要的配置选项。Spring使用注释来描述Bean的配置与采用XML相比，因类注释是在一个类源代码中，可以获得类型安全检查的好处。可以良好的支持重构。</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">JavaConfig就是使用注释来描述Bean配置的组件。JavaConfig 是Spring的一个子项目,</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">比起Spring，它还是一个非常年青的项目。目前的版本是1.0 M2。使用XML来配置Bean所能实现的功能，通过JavaConfig同样可以很好的实现。</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">&nbsp;</div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">2.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>HelloWorld with JavaConfig</font></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt"><strong><span style="FONT-SIZE: 12pt">2.1&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">获得</span></strong><strong><span style="FONT-SIZE: 12pt">JavaConfig</span></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">JavaConfig的下载地址：</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt"><a href="http://downloads.sourceforge.net/springframework/spring-javaconfig-1.0-m2-with-dependencies.zip?modtime=1178633399&amp;big_mirror=0">http://downloads.sourceforge.net/springframework/spring-javaconfig-1.0-m2-with-dependencies.zip?modtime=1178633399&amp;big_mirror=0</a></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">关于JavaConfig的更多信息请访问：</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt"><a href="http://www.springframework.org/node/455">http://www.springframework.org/node/455</a></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt"><strong><span style="FONT-SIZE: 12pt">2.2&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">HelloWorld</span></strong><strong><span style="FONT-SIZE: 12pt">程序</span></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">我们将以HelloWorld程序来开始JavaConfig之旅！</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">HelloWorld.java</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.springconfig.example.bean; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloWorld&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;</span><span class="keyword">private</span><span>&nbsp;String&nbsp;word; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;sayHello()&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;System.out.println(</span><span class="keyword">this</span><span>.word); &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;setWord(String&nbsp;word)&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;</span><span class="keyword">this</span><span>.word&nbsp;=&nbsp;word; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>}&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">HelloWorld.java是一个非常简单的java类。只有两个方法:</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">setWord()设置私有变量word的值。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">SayHello()打印出word的值</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">现在我们以JavaConfig来描述HellWorld这个Bean,而不是以xml方式描述。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">我们需要创建一个管理类，并加上适当的注释就可以了。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">
<div class="code_title">java 代码</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">上在的代码，我们创建了一个叫HelloWorldConfiguration的类，并加上了一个类级别的注释@Configuration.</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">这个类中，只有一个helloWorld()的方法，返回类型为HelloWorld。这个方法，首先会创建一个HelloWorld的实例，这个实例设置word属性为&quot;Hello world!&quot;,然后返回这个实例。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">这个方法有一个方法级别的注释@Bean</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">看起来，这个与普通的java类并没有什么不一样。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">但是这是一个非常简单的JavaConfig实现。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">如果把HelloWorld用xml来描述，等价于:</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span><!--l version=</sp--><span class="string">&quot;1.0&quot;</span><span>&nbsp;encoding=</span><span class="string">&quot;UTF-8&quot;</span><span>?&gt; &nbsp;&nbsp;</span></span> </span></li>
    <li class=""><span><!--CTYPE beans PUBLIC </sp--><span class="string">&quot;-//SPRING//DTD&nbsp;BEAN//EN&quot;</span><span>&nbsp;</span><span class="string">&quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span><beans></beans>&nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;<span class="string">&quot;helloWorld&quot;</span><span>&nbsp;</span><span class="keyword">class</span><span>=</span><span class="string">&quot;com.springconfig.example.bean.HelloWorld&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="string">&quot;word&quot;</span><span>&gt; &nbsp;&nbsp;</span> </span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<value></value>Hello&nbsp;world! &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;</span> </li>
</ol>
</div>
</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">JavaConfig的使用也非常的简单</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">HelloWorldWithJavaConfig.java</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.springconfig.example.chapter2; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;HelloWorldWithJavaConfig&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;ApplicationContext&nbsp;config&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(HelloWorldConfiguration.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;&nbsp;HelloWorld&nbsp;helloWorld&nbsp;=&nbsp;(HelloWorld)config.getBean(</span><span class="string">&quot;helloWorld&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;&nbsp;helloWorld.sayHello(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">程序运行后的输出结果如下：</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt"><span style="FONT-SIZE: 10pt; COLOR: black">Hello world!</span></div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">可见JavaConfig的使用与XML一样简单，只是这里AnootationApplicationcontext替代了ClassPathXmlApplicationContext.</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">再来看看HelloWorldConfiguration类。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">加上@Configuration注释后的HelloWorldConfiguration类就像一个描述Bean配置的XML文件。</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">加上@Bean注释后的helloWorld()方法就是一个Bean描述。Bean的ID为helloWorld.而Bean的class属性为com.springconfig.example.bean.HelloWorld.</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">并为这个Bean的word属性注入了值Hello world!</div>
<div style="MARGIN: 0cm 0cm 0pt 36pt">&nbsp;</div>
<div style="MARGIN: auto 0cm auto 36pt; TEXT-INDENT: -36pt"><strong><font size="5">3.<span style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>JavaConfig 注释</font></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">JavaConfig使用Java代码来对配置，管理和实例化Bean.并交由Spring容器来使用。在使用XML文件来描述Bean配置时，需要定义许多专有的XML元素。而使用Java代码来描述Bean配置，是利用JDK 5 的注释特性。不管是使用XML还是Java代码，Spring都使它们在语义上保持一致。让我们看看JavaConfig中那些最重要的注释</div>
<div style="MARGIN: 0cm 0cm 0pt 21pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt"><strong><span style="FONT-SIZE: 12pt">3.1&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">@Configuration</span></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Configuration 标志配置类,可以在这个配置类中定义bean。在第二章我们已经接触过。</div>
<div>&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Configuration</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">public class WebConfiguration{</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">//在这里定义Bean</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">}</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Configuration 等同于<beans></beans>标签。<beans></beans>标签的所有属性，都可以在@Configuration中进行定义。可以通过@Configuration的元素来自定义Configuration中bean的缺省的&ldquo;自动织入方式&rdquo;,&ldquo;依赖检查方式&rdquo;，&ldquo;延时初始化&rdquo;,及Configuration名称</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Configuration可选元素</div>
<p>
<table cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN-LEFT: 39pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse">
    <tbody>
        <tr>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>元素名</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>元素类型</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>说明</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>默认值</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>取值说明</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">defaultAutowire</span></strong></code></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>Autowire</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>默认自动织入方式</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><span style="FONT-SIZE: 10pt">INHERITED</span></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">defaultDependencyCheck</span></strong></code></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>DependencyCheck</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>默认依赖检查方式</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>DependencyCheck.<span style="FONT-SIZE: 10pt"> UNSPECIFIED </span><span style="FONT-SIZE: 10pt">，</span><span style="FONT-SIZE: 10pt">即不进行依赖检查</span></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">defaultLazy</span></strong></code></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>Lazy</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>默认延时初始化</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>Lazy.<span style="FONT-SIZE: 10pt"> UNSPECIFIED</span></div>
            <div><span style="FONT-SIZE: 10pt">即不进行延时初始化</span></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">names</span></strong></code></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>String[]</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>Configuration名称</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><span style="FONT-SIZE: 10pt">&quot;&quot;</span><span style="FONT-SIZE: 10pt">，</span><span style="FONT-SIZE: 10pt">默认为空字符串</span></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">useFactoryAspects</span></strong></code></div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>boolean</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.2pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>是否使用切面从封装的Bean工厂自动织入</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>false</div>
            </td>
            <td valign="top" width="114" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 85.25pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>true,false</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div><code>&nbsp;</code></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">deaultAutowire标记Bean的自动织入方式，其取值在</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">org.springframework.beans.factory.annotation.Autowire类中进行定义。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<p>
<table cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN-LEFT: 39pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse">
    <tbody>
        <tr>
            <td valign="top" width="89" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 66.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>模式</div>
            </td>
            <td valign="top" width="427" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 320.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>说明</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="89" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 66.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>INHERITED</div>
            </td>
            <td valign="top" width="427" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 320.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>不指定自动织入模式，从封装的factory中继承</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="89" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 66.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>NO</div>
            </td>
            <td valign="top" width="427" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 320.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>不使用自动织入</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="89" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 66.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>BY_NAME</div>
            </td>
            <td valign="top" width="427" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 320.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>根据名称织入bean的属性</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="89" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 66.8pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>BY_TYPE</div>
            </td>
            <td valign="top" width="427" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 320.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>根据类型织入bean的属性</div>
            </td>
        </tr>
        <tr>
            <td valign="top" colspan="2" width="516" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 387.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>注意：Autowire并没有定义constructor和autodetect这两种织入方式,也无需要这两种织入方式</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt"><code><strong><span style="FONT-SIZE: 10pt">DefaultDependencyCheck </span></strong></code><code><span style="FONT-SIZE: 10pt">标记</span></code><code><span style="FONT-SIZE: 10pt">Bean</span></code><code><span style="FONT-SIZE: 10pt">的依赖检查方式</span></code><code><span style="FONT-SIZE: 10pt">，</span></code><code><span style="FONT-SIZE: 10pt">其取值在</span></code>DependencyCheck中定义</div>
<p>
<table cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN-LEFT: 39pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse">
    <tbody>
        <tr>
            <td valign="top" width="87" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 65.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>模式</div>
            </td>
            <td valign="top" width="429" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 321.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>说明</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="87" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 65.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>UNSPECIFIED</div>
            </td>
            <td valign="top" width="429" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 321.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>不指定依赖检可方式，从封装的factory中继承</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="87" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 65.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>NONE</div>
            </td>
            <td valign="top" width="429" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 321.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>没有依赖检查</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="87" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 65.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>SIMPLE</div>
            </td>
            <td valign="top" width="429" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 321.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>对原始类型和集合进行依赖检查</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="87" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 65.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>OBJECTS</div>
            </td>
            <td valign="top" width="429" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 321.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>对对象进行依赖检查</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="87" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 65.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>ALL</div>
            </td>
            <td valign="top" width="429" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 321.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>对原始类，集合和对象都进行依赖检查</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt"><code><strong><span style="FONT-SIZE: 10pt">DefaultLazy </span></strong></code><code><span style="FONT-SIZE: 10pt">标记</span></code><code><span style="FONT-SIZE: 10pt">Bean</span></code><code><span style="FONT-SIZE: 10pt">是否进行延时初始化</span></code><code><span style="FONT-SIZE: 10pt">,</span></code><code><span style="FONT-SIZE: 10pt">其取值在</span></code><code><span style="FONT-SIZE: 10pt">Lazy</span></code><code><span style="FONT-SIZE: 10pt">类中定义</span></code></div>
<p>
<table cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; MARGIN-LEFT: 39pt; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse">
    <tbody>
        <tr>
            <td valign="top" width="111" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 83.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>模式</div>
            </td>
            <td valign="top" width="405" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 303.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>说明</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="111" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 83.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>UNSPECIFIED</div>
            </td>
            <td valign="top" width="405" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 303.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>不指定延时初始化Bean方式，从封装的factory中继承</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="111" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 83.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>FALSE</div>
            </td>
            <td valign="top" width="405" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 303.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>不进延时初始化Bean</div>
            </td>
        </tr>
        <tr>
            <td valign="top" width="111" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 83.4pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>TRUE</div>
            </td>
            <td valign="top" width="405" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 303.7pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; BACKGROUND-COLOR: transparent">
            <div>延时初始化Bean</div>
            </td>
        </tr>
    </tbody>
</table>
</p>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">示例：</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.springconfig.example.chapter3; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="annotation">@Configuration</span><span>(defaultAutowire=Autowire.BY_TYPE,defaultLazy=Lazy.FALSE) &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConfigurationFull&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ConfigurationSupport&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;HelloWorld&nbsp;helloWorld(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>HelloWorld&nbsp;helloWorld&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;HelloWorld(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>helloWorld.setWord(word()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">return</span><span>&nbsp;helloWorld; &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;String&nbsp;word(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>String&nbsp;word&nbsp;=</span><span class="string">&quot;HelloWorld!&quot;</span><span>; &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;word; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp; &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">需要注意的是使用@Configuration来注释一个java类后，这个配置类也会被定义成一个Bean.其Bean名称为这个Configuration类的完整类名。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.springconfig.example.chapter3; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConfigurationWithElement&nbsp;{ &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;</span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(ConfigurationFull.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;ConfigurationFull&nbsp;configuration&nbsp;=(ConfigurationFull)context.getBean(</span><span class="string">&quot;com.springconfig.example.chapter3.ConfigurationFull&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>&nbsp;configuration.helloWorld().sayHello(); &nbsp;&nbsp;</span> </li>
    <li class=""><span>&nbsp;} &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
运行程序后，输出：</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt"><span style="FONT-SIZE: 10pt; COLOR: black">HelloWorld!</span></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">在Configuration中访问Factory</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">有时需要在Configuration类中获得Factory对象，可以继承ConfigurationSupport。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">package</span><span>&nbsp;com.springconfig.example.chapter3; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="annotation">@Configuration</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">class</span><span>&nbsp;ConfigurationWithSupport&nbsp;</span><span class="keyword">extends</span><span>&nbsp;ConfigurationSupport{ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">public</span><span>&nbsp;String&nbsp;sayWord(){ &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>String&nbsp;word&nbsp;=&nbsp;(String)getBean(</span><span class="string">&quot;word&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;word;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
    <li class=""><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">在sayWord方法中，是能过getBean方法来获得一个名为word的Bean,并返回这个Bean的值。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String[]&nbsp;args){ &nbsp;&nbsp;</span></span> </li>
    <li class=""><span>ApplicationContext&nbsp;context&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;AnnotationApplicationContext(ConfigurationFull.</span><span class="keyword">class</span><span>.getName(),ConfigurationWithSupport.</span><span class="keyword">class</span><span>.getName()); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>String&nbsp;word&nbsp;=&nbsp;(String)context.getBean(</span><span class="string">&quot;sayWord&quot;</span><span>); &nbsp;&nbsp;</span> </li>
    <li class=""><span>System.out.println(word); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt; TEXT-INDENT: -18pt"><strong><span style="FONT-SIZE: 12pt">3.2&nbsp;</span></strong><strong><span style="FONT-SIZE: 12pt">@Bean</span></strong></div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Bean用来在Configuration中指定一个Bean定义。方法名就是Bean名称。当然你也可以使用aliases元素来为bean取一个别名。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar"></div>
<ol class="dp-j">
    <li class="alt"><span><span>&nbsp; &nbsp;&nbsp;</span></span> </li>
    <li class=""><span></span><span class="annotation">@Bean</span><span>&nbsp;&nbsp;</span> </li>
    <li class="alt"><span></span><span class="keyword">public</span><span>&nbsp;HelloWorld&nbsp;helloWorld(){ &nbsp;&nbsp;</span> </li>
    <li class=""><span>HelloWorld&nbsp;helloWorld&nbsp;=&nbsp;</span><span class="keyword">new</span><span>&nbsp;HelloWorld(); &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>helloWorld.setWord(word()); &nbsp;&nbsp;</span> </li>
    <li class=""><span></span><span class="keyword">return</span><span>&nbsp;helloWorld; &nbsp;&nbsp;</span> </li>
    <li class="alt"><span>} &nbsp;&nbsp;</span> </li>
</ol>
</div>
&nbsp;</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">例如：上面的例子，spring就像创造一个名称叫helloWorld的bean。返回值为HelloWorld类型的实例。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Bean 是一个方法级的注释，用java代码来创建和装配一个Bean实列。它相当于<bean></bean>标签，并可以支持xml的<bean></bean>标签提供的大部分选项，如：autowiring,lazy-init,dependency-check,depends-on,scope等。</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">@Bean的可选元素</div>
<div style="MARGIN: 0cm 0cm 0pt 39pt">
<table cellspacing="0" border="1" cellpadding="0" style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse">
    <tbody>
        <tr style="HEIGHT: 15.3pt">
            <td valign="top" width="134" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 100.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 15.3pt; BACKGROUND-COLOR: transparent">
            <div>元素名</div>
            </td>
            <td valign="top" width="120" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 15.3pt; BACKGROUND-COLOR: transparent">
            <div>元素类型</div>
            </td>
            <td valign="top" width="96" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 15.3pt; BACKGROUND-COLOR: transparent">
            <div>说明</div>
            </td>
            <td valign="top" width="124" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 15.3pt; BACKGROUND-COLOR: transparent">
            <div>默认值</div>
            </td>
            <td valign="top" width="68" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 0.5pt solid; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 15.3pt; BACKGROUND-COLOR: transparent">
            <div>取值说明</div>
            </td>
        </tr>
        <tr style="HEIGHT: 16.15pt">
            <td valign="top" width="134" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 100.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 16.15pt; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">aliases</span></strong></code></div>
            </td>
            <td valign="top" width="120" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 16.15pt; BACKGROUND-COLOR: transparent">
            <div>String[]</div>
            </td>
            <td valign="top" width="96" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 16.15pt; BACKGROUND-COLOR: transparent">
            <div>Bean的别名</div>
            </td>
            <td valign="top" width="124" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 16.15pt; BACKGROUND-COLOR: transparent">
            <div><span style="FONT-SIZE: 10pt">{}</span></div>
            </td>
            <td valign="top" width="68" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 16.15pt; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr style="HEIGHT: 46.9pt">
            <td valign="top" width="134" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 100.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 46.9pt; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">dependencyCheck</span></strong></code></div>
            </td>
            <td valign="top" width="120" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 46.9pt; BACKGROUND-COLOR: transparent">
            <div>DependencyCheck</div>
            </td>
            <td valign="top" width="96" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 46.9pt; BACKGROUND-COLOR: transparent">
            <div>默认依赖检查方式</div>
            </td>
            <td valign="top" width="124" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 46.9pt; BACKGROUND-COLOR: transparent">
            <div>DependencyCheck.<span style="FONT-SIZE: 10pt"> UNSPECIFIED </span><span style="FONT-SIZE: 10pt">，</span><span style="FONT-SIZE: 10pt">即不进行依赖检查</span></div>
            </td>
            <td valign="top" width="68" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 46.9pt; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr style="HEIGHT: 63.15pt">
            <td valign="top" width="134" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 100.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 63.15pt; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">allowOverriding</span></strong></code></div>
            </td>
            <td valign="top" width="120" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 63.15pt; BACKGROUND-COLOR: transparent">
            <div>boolean</div>
            </td>
            <td valign="top" width="96" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 63.15pt; BACKGROUND-COLOR: transparent">
            <div>允许覆盖xml或其它Configuration的bean</div>
            </td>
            <td valign="top" width="124" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 63.15pt; BACKGROUND-COLOR: transparent">
            <div>false</div>
            </td>
            <td valign="top" width="68" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 51.3pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 63.15pt; BACKGROUND-COLOR: transparent">
            <div>&nbsp;</div>
            </td>
        </tr>
        <tr style="HEIGHT: 31.6pt">
            <td valign="top" width="134" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: windowtext 0.5pt solid; WIDTH: 100.6pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 31.6pt; BACKGROUND-COLOR: transparent">
            <div><code><strong><span style="FONT-SIZE: 10pt">autowire</span></strong></code></div>
            </td>
            <td valign="top" width="120" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 90.1pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 31.6pt; BACKGROUND-COLOR: transparent">
            <div>AutoWire</div>
            </td>
            <td valign="top" width="96" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 72.35pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 31.6pt; BACKGROUND-COLOR: transparent">
            <div>自动织入方式</div>
            </td>
            <td valign="top" width="124" style="BORDER-RIGHT: windowtext 0.5pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #d4d0c8; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; WIDTH: 93.05pt; PADDING-TOP: 0cm; BORDER-BOTTOM: windowtext 0.5pt solid; HEIGHT: 31.6pt; BACKGROUND-COLOR: transparent">
            <div><span style="FONT-SIZE: 10pt">INHERITED</span></div>
            </td>
            <td valign="top" width="68" style="BORDER-RIGHT: windowtext 0.5pt s