﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-JOY工作室---Java-文章分类-Spring</title><link>http://www.blogjava.net/wuhen86/category/40548.html</link><description>Jump Over yourself !</description><language>zh-cn</language><lastBuildDate>Sat, 31 Jul 2010 01:20:43 GMT</lastBuildDate><pubDate>Sat, 31 Jul 2010 01:20:43 GMT</pubDate><ttl>60</ttl><item><title>Java普通类获取Spring框架Bean 的五种方法</title><link>http://www.blogjava.net/wuhen86/articles/315472.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Mon, 15 Mar 2010 05:44:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/315472.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/315472.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/315472.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/315472.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/315472.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: 宋体;">方法一：在初始化时保存</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext</span><span style="font-size: 9pt; font-family: 宋体;">对象</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: 宋体;">代码：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
ApplicationContext
ac = new FileSystemXmlApplicationContex("applicationContext.xml");<br />
&nbsp;&nbsp;&nbsp;
ac.getBean("beanId");<br />
&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">说明：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">这种方式适用于采用</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">框架的独立应用程序，需要程序通过配置文件手工初始化</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">的情况。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;<br />
</span><span style="font-size: 9pt; font-family: 宋体;">方法二：通过</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">提供的工具类获取</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext</span><span style="font-size: 9pt; font-family: 宋体;">对象</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 9pt; font-family: 宋体;">代码：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;import
org.springframework.web.context.support.WebApplicationContextUtils;<br />
ApplicationContext
ac1 =
WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext
sc)<br />
ApplicationContext ac2 =
WebApplicationContextUtils.getWebApplicationContext(ServletContext sc)<br />
&nbsp;&nbsp;&nbsp;
ac1.getBean("beanId");<br />
&nbsp;&nbsp;&nbsp; ac2.getBean("beanId");<br />
&nbsp;</span><span style="font-size: 9pt; font-family: 宋体;">说明：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; font-family: 宋体;">这种方式适合于采用</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">框架的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">B/S</span><span style="font-size: 9pt; font-family: 宋体;">系统，通过</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ServletContext</span><span style="font-size: 9pt; font-family: 宋体;">对象获取</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext</span><span style="font-size: 9pt; font-family: 宋体;">对象，然后在通过它获取需要的类实例。上面两个工具方式的区别
是，前者在获取失败时抛出异常，后者返回</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">null</span><span style="font-size: 9pt; font-family: 宋体;">。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 9pt; font-family: 宋体;">其
中</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">
servletContext sc </span><span style="font-size: 9pt; font-family: 宋体;">可
以具体</span><span style="font-size: 9pt; font-family: Verdana;"> </span><span style="font-size: 9pt; font-family: 宋体;">换成</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">
servlet.getServletContext()</span><span style="font-size: 9pt; font-family: 宋体;">或者</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"> this.getServletContext() </span><span style="font-size: 9pt; font-family: 宋体;">或者</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">
request.getSession().getServletContext();<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: 宋体;">另外，由于</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">spring</span><span style="font-size: 9pt; font-family: 宋体;">是注入的对象放在</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ServletContext</span><span style="font-size: 9pt; font-family: 宋体;">中的，所以可以直接在</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ServletContext</span><span style="font-size: 9pt; font-family: 宋体;">取出</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">WebApplicationContext
</span><span style="font-size: 9pt; font-family: 宋体;">对象：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">WebApplicationContext webApplicationContext =
(WebApplicationContext)
servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;<br />
</span><span style="font-size: 9pt; font-family: 宋体;">方法三：继承自抽象类</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationObjectSupport<br />
&nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; font-family: 宋体;">说明：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">抽象类</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationObjectSupport</span><span style="font-size: 9pt; font-family: 宋体;">提供</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">getApplicationContext()</span><span style="font-size: 9pt; font-family: 宋体;">方法，可以方便的获取到</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext</span><span style="font-size: 9pt; font-family: 宋体;">。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">初始化时，会通过该抽象类的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">setApplicationContext(ApplicationContext
context)</span><span style="font-size: 9pt; font-family: 宋体;">方法将</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext
</span><span style="font-size: 9pt; font-family: 宋体;">对象注入。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">&nbsp;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: 宋体;">方法四：继承自抽象类</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">WebApplicationObjectSupport<br />
&nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; font-family: 宋体;">说明：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">类似上面方法，调用</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">getWebApplicationContext()</span><span style="font-size: 9pt; font-family: 宋体;">获取</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">WebApplicationContext<br />
&nbsp;<br />
</span><span style="font-size: 9pt; font-family: 宋体;">方法五：实现接口</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContextAware<br />
&nbsp;&nbsp;</span><span style="font-size: 9pt; font-family: 宋体;">说明：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">实现该接口的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">setApplicationContext(ApplicationContext
context)</span><span style="font-size: 9pt; font-family: 宋体;">方法，并保存</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext
</span><span style="font-size: 9pt; font-family: 宋体;">对象。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">初始化时，会通过该方法将</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">ApplicationContext
</span><span style="font-size: 9pt; font-family: 宋体;">对象注入。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
&nbsp;<br />
</span><span style="font-size: 9pt; font-family: 宋体;">以上方法适合不同的情况，请根据具体情况选用相应的方法。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 9pt; font-family: 宋体;">这里值得提一点的是，系统中用到上述方法的类实际上就于</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">框架紧密耦合在一起了，因为这些类是知道它们是运行在</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Spring</span><span style="font-size: 9pt; font-family: 宋体;">框架上的，因此，系统中，应该尽量的减少这类应用，使系统尽可能
的独立于当前运行环境，尽量通过</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">DI</span><span style="font-size: 9pt; font-family: 宋体;">的方式获取需要的服务提供者。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">&nbsp;<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">然
后在</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Action</span><span style="font-size: 9pt; font-family: 宋体;">中
编写如下代码得到</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Context</span><span style="font-size: 9pt; font-family: 宋体;">，（我是覆盖了</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">Struts Action</span><span style="font-size: 9pt; font-family: 宋体;">的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">setServlet</span><span style="font-size: 9pt; font-family: 宋体;">方法，也许还有更好的方法）。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp; public void setServlet(ActionServlet servlet){<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
super.setServlet(servlet);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ServletContext servletContext =
servlet.getServletContext();<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: red;">WebApplicationContext
wac =&nbsp;&nbsp;&nbsp;
WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);<br />
</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
// get yours beans<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp; }<br />
<br />
<br />
</span><span style="font-size: 9pt; font-family: 宋体;">我需要在</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">spring</span><span style="font-size: 9pt; font-family: 宋体;">的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">bean</span><span style="font-size: 9pt; font-family: 宋体;">中直接获取，这下可和我们常规的操作有些不同，因为</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">spring</span><span style="font-size: 9pt; font-family: 宋体;">的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">bean</span><span style="font-size: 9pt; font-family: 宋体;">都是</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">pojo</span><span style="font-size: 9pt; font-family: 宋体;">的。根本见不着</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">servletconfig</span><span style="font-size: 9pt; font-family: 宋体;">和</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">servletcontext</span><span style="font-size: 9pt; font-family: 宋体;">的影子。</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">&nbsp; </span><span style="font-size: 9pt; font-family: 宋体;">这里我
需要指出</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">spring</span><span style="font-size: 9pt; font-family: 宋体;">给
我们提供了两个接口：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">org.springframework.web.context.ServletContextAware</span><span style="font-size: 9pt; font-family: 宋体;">和</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">org.springframework.web.context.ServletConfigAware</span><span style="font-size: 9pt; font-family: 宋体;">。我们可以让我们的</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">bean</span><span style="font-size: 9pt; font-family: 宋体;">实现上边的任何一个接口就能获取到</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US">servletContext</span><span style="font-size: 9pt; font-family: 宋体;">了</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"> .<o:p></o:p></span></p>
<p class="MsoNormal" style="margin: 0cm 0cm 0pt; text-align: left;" align="left"><span style="font-size: 9pt; font-family: 宋体;">代码如下：</span><span style="font-size: 9pt; font-family: Verdana;" lang="EN-US"><o:p></o:p></span></p>
<span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">public</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> </span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">class</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> DicBean </span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">implements</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> ServletContextAware</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">{</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">private</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> ServletContext
servletContext</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">;</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
<br />
</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">public</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> </span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">void</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> setServletContext</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">(</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">ServletContext sc</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">)</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US"> </span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">{</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt; color: blue; line-height: 150%; font-family: 宋体;" lang="EN-US">this</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">.</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">servletContext</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">=</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">sc</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">;</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="font-size: 12pt; color: red; line-height: 150%; font-family: 宋体;" lang="EN-US">System</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">.</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">out</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">.</span><span style="font-size: 12pt; color: red; line-height: 150%; font-family: 宋体;" lang="EN-US">println</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">(</span><span style="font-size: 12pt; color: fuchsia; line-height: 150%; font-family: 宋体;" lang="EN-US">"</span><span style="font-size: 12pt; color: fuchsia; line-height: 150%; font-family: 宋体;">项目的绝对路径为：<span lang="EN-US">"</span></span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">+</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">servletContext</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">.</span><span style="font-size: 12pt; color: black; line-height: 150%; font-family: 宋体;" lang="EN-US">getRealPath</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">(</span><span style="font-size: 12pt; color: fuchsia; line-height: 150%; font-family: 宋体;" lang="EN-US">"/"</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">));</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">}</span><span style="font-size: 9pt; color: black; line-height: 150%; font-family: Verdana;" lang="EN-US"><br />
</span><span style="font-size: 12pt; color: #0000cc; line-height: 150%; font-family: 宋体;" lang="EN-US">}</span>
<img src ="http://www.blogjava.net/wuhen86/aggbug/315472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2010-03-15 13:44 <a href="http://www.blogjava.net/wuhen86/articles/315472.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring-mvc 的处理流程 </title><link>http://www.blogjava.net/wuhen86/articles/291496.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Mon, 17 Aug 2009 06:59:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/291496.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/291496.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/291496.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/291496.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/291496.html</trackback:ping><description><![CDATA[Spring-mvc 的处理流程<br />
请求的分发<br />
<br />
请求首先到达DispatcherServlet，应用服务器会根据Web应用中web.xml文件定义的url映射将相应的请求分发到DispatcherServlet中<br />
<br />
请求的处理<br />
<br />
DispatcherServlet会查找相应的HandlerMapping接口的实现类，调用其中的方法：HandlerExecutionChain getHandler(HttpServletRequest request) throwsException，该方法会返回一个HandlerExecutionChain。返回的HandlerExecutionChain中包含了零个或者是多个Interceptor和一个处理请求的Handler。DispatcherServlet会调用Interceptor中的 preHandle()方法。然后处理Handler，这个Handler相当于Struts中Action，在SpringMVC中默认的实现是Controller接口，是具体处理请求的代码所驻留的地方。事实上HandlerExecutionChain中的getHandler()返回的是一个Object类型。DispatcherServlet不会直接调用getHandler（）返回对象中的方法，DispatcherServlet会查找相应的HandlerAdapter，然后具体通过HandlerAdapter来调用getHandler() 返回的handler对象中的方法。就是说我们可以实现自己的HandlerAdapter然后通过IoC注入到DispatcherServlet中，从而可以实现一套自定义的控制器。随后DispatcherServlet会调用Interceptor中的postHandle()方法。<br />
<br />
视图的处理<br />
<br />
DispatcherServlet会期望Hander返回一个ModelAndView，DispatcherServlet会根据所返回的ModelAndView对象所包含的信息进行视图的渲染。起具体出来流程如下：<br />
<br />
首先DispatcherServlet会根据LocaleResolver来识别请求中的Locale，开发人员可以自己实现LocaleResolver接口，然后通过IoC注入到DispatcherServlet中，然后DispatcherServlet 会判断ModelAndView中是否已经包含了接口View的具体实现，如果包含了，则直接调用View中的方法render(Map model,HttpServletRequest request, HttpServletResponseresponse)。如果不包含，则说明该ModelAndView只是包含了View的名称引用，DispatcherServlet会调用ViewResolver中的resolveViewName(String viewName, Localelocale)来解析其真正的视图。该方法会返回一个View的具体实现。<br />
<br />
视图的渲染<br />
<br />
Spring支持多种视图技术，其中比较常用的包括有Jstl视图，Veloctiy视图，FreeMarker视图等。对Jstl视图的渲染 Spring是通过JstlView这个类具体实现的。事实上其最终的渲染是交给容器来做的，Spring只是通过RequestDispatcher实现了服务器内部请求的Forward。而对于模板视图，如Veloctiy和FreeMarker等，Spring会初始化其相应的模板引擎，由模板引擎生成最终的Html页面然后在合并到Response的输出流中。<br />
<br />
异常的处理<br />
<br />
如果在Hander中处理请求是抛出异常，DispatcherServlet会查找HandlerExceptionResolver接口的具体实现，该接口定义了一个方法：<br />
<br />
ModelAndView resolveException(HttpServletRequest request,HttpServletResponse response, Object handler, Exceptionex)，实现类需要实现该方法以便对异常进行处理，最后该方法需要返回一个ModelAndView。
<img src ="http://www.blogjava.net/wuhen86/aggbug/291496.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2009-08-17 14:59 <a href="http://www.blogjava.net/wuhen86/articles/291496.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring 框架简介(轉載) </title><link>http://www.blogjava.net/wuhen86/articles/288968.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Wed, 29 Jul 2009 14:08:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/288968.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/288968.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/288968.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/288968.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/288968.html</trackback:ping><description><![CDATA[<p><a name="1"><span class="atitle">Spring 框架</span></a></p>
<p>如图 1 所示。</p>
<br />
<a name="fig1"><strong>图 1. Spring 框架的 7 个模块</strong></a><br />
<img height="288" alt="Spring 框架图示" src="http://www.ibm.com/developerworks/cn/java/wa-spring1/spring_framework.gif" width="555" /> <br />
<p>组成 Spring 框架的每个模块（或组件）都可以单独存在，或者与其他一个或多个模块联合实现。每个模块的功能如下：
<ul>
    <li><strong>核心容器</strong>：核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 <code>BeanFactory</code>，它是工厂模式的实现。<code>BeanFactory</code> 使用<em>控制反转</em> （IOC） 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
    <li><strong>Spring 上下文</strong>：Spring 上下文是一个配置文件，向 Spring 框架提供上下文信息。Spring 上下文包括企业服务，例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
    <li><strong>Spring AOP</strong>：通过配置管理特性，Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以，可以很容易地使 Spring 框架管理的任何对象支持 AOP。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP，不用依赖 EJB 组件，就可以将声明性事务管理集成到应用程序中。
    <li><strong>Spring DAO</strong>：JDBC DAO 抽象层提供了有意义的异常层次结构，可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理，并且极大地降低了需要编写的异常代码数量（例如打开和关闭连接）。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
    <li><strong>Spring ORM</strong>：Spring 框架插入了若干个 ORM 框架，从而提供了 ORM 的对象关系工具，其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
    <li><strong>Spring Web 模块</strong>：Web 上下文模块建立在应用程序上下文模块之上，为基于 Web 的应用程序提供了上下文。所以，Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
    <li><strong>Spring MVC 框架</strong>：MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口，MVC 框架变成为高度可配置的，MVC 容纳了大量视图技术，其中包括 JSP、Velocity、Tiles、iText 和 POI。 </li>
</ul>
<p>&nbsp;</p>
<p>Spring 框架的功能可以用在任何 J2EE 服务器中，大多数功能也适用于不受管理的环境。Spring 的核心要点是：支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问，这样的对象可以在不同 J2EE 环境 （Web 或 EJB）、独立应用程序、测试环境之间重用。 </p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="2"><span class="atitle">IOC 和 AOP</span></a></p>
<p>控制反转模式（也称作依赖性介入）的基本概念是：不创建对象，但是描述创建它们的方式。在代码中不直接与对象和服务连接，但在配置文件中描述哪一个组件需要哪一项服务。容器 （在 Spring 框架中是 IOC 容器） 负责将这些联系在一起。</p>
<p>在典型的 IOC 场景中，容器创建了所有对象，并设置必要的属性将它们连接在一起，决定什么时间调用方法。下表列出了 IOC 的一个实现模式。</p>
<table cellspacing="4" cellpadding="2" width="80%" border="1">
    <tbody>
        <tr valign="top">
            <td>类型 1</td>
            <td>服务需要实现专门的接口，通过接口，由对象提供这些服务，可以从对象查询依赖性（例如，需要的附加服务）</td>
        </tr>
        <tr valign="top">
            <td>类型 2</td>
            <td>通过 JavaBean 的属性（例如 setter 方法）分配依赖性</td>
        </tr>
        <tr valign="top">
            <td>类型 3</td>
            <td>依赖性以构造函数的形式提供，不以 JavaBean 属性的形式公开</td>
        </tr>
    </tbody>
</table>
<p>Spring 框架的 IOC 容器采用类型 2 和类型3 实现。</p>
<p><a name="N100FB"><span class="smalltitle">面向方面的编程</span></a></p>
<p><em>面向方面的编程</em>，即 AOP，是一种编程技术，它允许程序员对横切关注点或横切典型的职责分界线的行为（例如日志和事务管理）进行模块化。AOP 的核心构造是<em>方面</em>，它将那些影响多个类的行为封装到可重用的模块中。</p>
<p>AOP 和 IOC 是补充性的技术，它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中，可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中，可以反过来将日志服务<em>模块化</em>，并以声明的方式将它们应用到需要日志的组件上。当然，优势就是 Java 类不需要知道日志服务的存在，也不需要考虑相关的代码。所以，用 Spring AOP 编写的应用程序代码是松散耦合的。</p>
<p>AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="3"><span class="atitle">IOC 容器</span></a></p>
<p>Spring 设计的核心是 <code>org.springframework.beans</code> 包，它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用，而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 <code>BeanFactory</code> 接口，它是工厂设计模式的实现，允许通过名称创建和检索对象。<code>BeanFactory</code> 也可以管理对象之间的关系。</p>
<p><code>BeanFactory</code> 支持两个对象模型。</p>
<ul>
    <li><strong>单态</strong> 模型提供了具有特定名称的对象的共享实例，可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。
    <li><strong>原型</strong> 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时，原型模型最适合。 </li>
</ul>
<p>bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。正如我将在下一个示例中演示的那样，Spring 框架使用 JavaBean 属性和配置数据来指出必须设置的依赖关系。</p>
<p><a name="N10143"><span class="smalltitle">BeanFactory 接口</span></a></p>
<p>因为 <code>org.springframework.beans.factory.BeanFactory</code> 是一个简单接口，所以可以针对各种底层存储方法实现。最常用的 <code>BeanFactory</code> 定义是 <code>XmlBeanFactory</code>，它根据 XML 文件中的定义装入 bean，如清单 1 所示。</p>
<br />
<a name="N10159"><strong>清单 1. XmlBeanFactory</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">BeanFactory factory = new XMLBeanFactory(new FileInputSteam("mybean.xml"));
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>在 XML 文件中定义的 Bean 是被消极加载的，这意味在需要 bean 之前，bean 本身不会被初始化。要从 <code>BeanFactory</code> 检索 bean，只需调用 <code>getBean()</code> 方法，传入将要检索的 bean 的名称即可，如清单 2 所示。</p>
<br />
<a name="N1016F"><strong>清单 2. getBean()</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">MyBean mybean = (MyBean) factory.getBean("mybean");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>每个 bean 的定义都可以是 POJO （用类名和 JavaBean 初始化属性定义） 或 <code>FactoryBean</code>。<code>FactoryBean</code> 接口为使用 Spring 框架构建的应用程序添加了一个间接的级别。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="4"><span class="atitle">IOC 示例</span></a></p>
<p>理解控制反转最简单的方式就是看它的实际应用。在对由三部分组成的 <em>Spring 系列</em> 的第 1 部分进行总结时，我使用了一个示例，演示了如何通过 Spring IOC 容器注入应用程序的依赖关系（而不是将它们构建进来）。</p>
<p>我用开启在线信用帐户的用例作为起点。对于该实现，开启信用帐户要求用户与以下服务进行交互：
<ul>
    <li>信用级别评定服务，查询用户的信用历史信息。
    <li>远程信息链接服务，插入客户信息，将客户信息与信用卡和银行信息连接起来，以进行自动借记（如果需要的话）。
    <li>电子邮件服务，向用户发送有关信用卡状态的电子邮件。 </li>
</ul>
<p>&nbsp;</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="5"><span class="atitle">三个接口</span></a></p>
<p>对于这个示例，我假设服务已经存在，理想的情况是用松散耦合的方式把它们集成在一起。以下清单显示了三个服务的应用程序接口。</p>
<br />
<a name="N101AB"><strong>清单 3. CreditRatingInterface</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">public interface CreditRatingInterface {
            public boolean getUserCreditHistoryInformation(ICustomer iCustomer);
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>清单 3 所示的信用级别评定接口提供了信用历史信息。它需要一个包含客户信息的 <code>Customer</code> 对象。该接口的实现是由 <code>CreditRating</code> 类提供的。</p>
<br />
<a name="N101C1"><strong>清单 4. CreditLinkingInterface</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">public interface CreditLinkingInterface {
            public String getUrl();
            public void setUrl(String url);
            public void linkCreditBankAccount() throws Exception ;
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p>信用链接接口将信用历史信息与银行信息（如果需要的话）连接在一起，并插入用户的信用卡信息。信用链接接口是一个远程服务，它的查询是通过 <code>getUrl()</code> 方法进行的。URL 由 Spring 框架的 bean 配置机制设置，我稍后会讨论它。该接口的实现是由 <code>CreditLinking</code> 类提供的。</p>
<br />
<a name="N101D7"><strong>清单 5. EmailInterface</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">public interface EmailInterface {
            public void sendEmail(ICustomer iCustomer);
            public String getFromEmail();
            public void setFromEmail(String fromEmail) ;
            public String getPassword();
            public void setPassword(String password) ;
            public String getSmtpHost() ;
            public void setSmtpHost(String smtpHost);
            public String getUserId() ;
            public void setUserId(String userId);
            }
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<p><code>EmailInterface</code> 负责向客户发送关于客户信用卡状态的电子邮件。邮件配置参数（例如 SMPT 主机、用户名、口令）由前面提到的 bean 配置机制设置。<code>Email</code> 类提供了该接口的实现。</p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<p><a name="6"><span class="atitle">Spring 使其保持松散</span></a></p>
<p>这些接口就位之后，接下来要考虑的就是如何用松散耦合方式将它们集成在一起。在 <a href="http://www.ibm.com/developerworks/cn/java/wa-spring1/listing1.html" cmimpressionsent="1">清单 6</a> 中可以看到信用卡帐户用例的实现。</p>
<p>注意，所有的 setter 方法都是由 Spring 的配置 bean 实现的。所有的依赖关系 （也就是三个接口）都可以由 Spring 框架用这些 bean 注入。<code>createCreditCardAccount()</code> 方法会用服务去执行其余实现。在 <a href="http://www.ibm.com/developerworks/cn/java/wa-spring1/listing2.html" cmimpressionsent="1">清单 7 </a>中可以看到 Spring 的配置文件。我用箭头突出了这些定义。 </p>
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="7"><span class="atitle">运行应用程序</span></a></p>
<p>要运行示例应用程序，首先必须 <a href="http://prdownloads.sourceforge.net/" target="_new" cmimpressionsent="1">下载 Spring 框架</a> 及其所有依赖文件。接下来，将框架释放到（比如说）磁盘 <em>c:\</em>，这会创建 <em>C:\spring-framework-1.2-rc2</em> （适用于当前发行版本） 这样的文件夹。在继续后面的操作之前，还必须下载和释放 <a href="http://ant.apache.org/" target="_new" cmimpressionsent="1">Apache Ant</a>。</p>
<p>接下来，将源代码释放到文件夹，例如 <em>c:\</em> 盘，然后创建 <em>SpringProject</em>。将 Spring 库（即 <em>C:\spring-framework-1.2-rc2\dist</em> 下的 <em>spring.jar</em> 和 <em>C:\spring-framework-1.2-rc2\lib\jakarta-commons</em> 下的 <em>commons-logging.jar</em>）复制到 <em>SpringProject\lib</em> 文件夹中。完成这些工作之后，就有了必需的构建依赖关系集。</p>
<p>打开命令提示符，将当前目录切换到 <em>SpringProject</em>，在命令提示符中输入以下命令：<code>build</code>。 </p>
<p>这会构建并运行 <code>CreateCreditAccountClient</code> 类，类的运行将创建 <code>Customer</code> 类对象并填充它，还会调用 <code>CreateCreditCardAccount</code> 类创建并链接信用卡帐户。<code>CreateCreditAccountClient</code> 还会通过 <code>ClassPathXmlApplicationContext</code> 装入 Spring 配置文件。装入 bean 之后，就可以通过 <code>getBean()</code> 方法访问它们了，如清单 8 所示。</p>
<br />
<a name="code8"><strong>清单 8. 装入 Spring 配置文件</strong></a><br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td class="code-outline">
            <pre class="displaycode">ClassPathXmlApplicationContext appContext =
            new ClassPathXmlApplicationContext(new String[] {
            "springexample-creditaccount.xml"
            });
            CreateCreditCardAccountInterface creditCardAccount =
            (CreateCreditCardAccountInterface)
            appContext.getBean("createCreditCard");
            </pre>
            </td>
        </tr>
    </tbody>
</table>
<br />
<br />
<table cellspacing="0" cellpadding="0" width="100%" border="0">
    <tbody>
        <tr>
            <td><img height="1" alt="" src="http://www.ibm.com/i/v14/rules/blue_rule.gif" width="100%" /><br />
            <img height="6" alt="" src="http://www.ibm.com/i/c.gif" width="8" border="0" /></td>
        </tr>
    </tbody>
</table>
<br />
<p><a name="8"><span class="atitle">结束语</span></a></p>
<p>在这篇由三部分组成的 <em>Spring 系列</em> 的第一篇文章中，我介绍了 Spring 框架的基础。我从讨论组成 Spring 分层架构的 7 个模块开始，然后深入介绍了其中两个模块：Spring AOP 和 IOC 容器。</p>
<p>由于学习的最佳方法是实践，所以我用一个工作示例介绍了 IOC 模式 （像 Spring 的 IOC 容器实现的那样）如何用松散耦合的方式将分散的系统集成在一起。在这个示例中可以看到，将依赖关系或服务注入工作中的信用卡帐户应用程序，要比从头开始构建它们容易得多。</p>
<p>请继续关注这一系列的下一篇文章，我将在这里学习的知识基础上，介绍 Spring AOP 模块如何在企业应用程序中提供持久支持，并让您开始了解 Spring MVC 模块和相关插件。 <br />
<a href="http://www.ibm.com/developerworks/cn/java/wa-spring1/">轉載地址:http://www.ibm.com/developerworks/cn/java/wa-spring1/</a></p>
<img src ="http://www.blogjava.net/wuhen86/aggbug/288968.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2009-07-29 22:08 <a href="http://www.blogjava.net/wuhen86/articles/288968.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Spring MVC 中的 MultiActionController 用法详解 (转载)</title><link>http://www.blogjava.net/wuhen86/articles/288966.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Wed, 29 Jul 2009 14:04:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/288966.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/288966.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/288966.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/288966.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/288966.html</trackback:ping><description><![CDATA[<p>Spring MVC 中 Controller 的层次实在是多，有些眼花缭乱了。在单个的基础上，再新加两三个叫做丰富，再多就未必是好事，反而会令人缩手新闻片脚，无从定夺。<br />
多数 Controller 都是只完成一个任务，不过也有一个像 Struts 的 DispatchAction 的那样的 Conntroller，<br />
org.springframework.web.servlet.mvc.multiaction.MultiActionController，意即在一个 Controller 中处理多个动作，<br />
如同一个业务的增、删、改可以放在一起了。不至于增、删、改各自为政，造成代码混乱、重复难以维护。</p>
<p>&nbsp;本文中的 web.xml 的 org.springframework.web.servlet.DispatcherServlet 所处理的 url-pattern 是 *.html，<br />
&nbsp;如何搭建 Spring MVC 项目不细加说明，可参考我前面同系列的文章。</p>
<p>例如，下面的 UserController，有两个签名一样的 updateUser() 和 deleteUser() 方法</p>
<p>public class UserController extends MultiActionController {　<br />
　　public ModelAndView updateUser(HttpServletRequest request,　<br />
　　　　　　HttpServletResponse response) {　<br />
　　　　System.out.println("updateUser");//方便于跟踪执行了哪个方法　<br />
　　　　return new ModelAndView("userList","from","updateUser");　<br />
　　}　<br />
　　public ModelAndView deleteUser(HttpServletRequest request,　<br />
　　　　　　HttpServletResponse response) {　<br />
　　　　System.out.println("deleteUser");//方便于跟踪执行了哪个方法　<br />
　　　　return new ModelAndView("userList","from","deleteUser");　<br />
　　}　<br />
}　</p>
<p>用过 Struts 的 DispatchAction 的都知道，是通过 http://.../userAction.do?method=updateUser 的方式来指定执行哪个方法。<br />
那 Spring MVC中是如何定位到所需方法上呢？</p>
<p>　　Spring MVC 除了有一个叫做 HandlerMapping(把 URL 解析到 Controller) 的东西，还要把操作进一步解析到方法名上，<br />
即要找到的 Controller 上的哪个方法并执行之。缺省的方法名解析器是 InternalPathMethodNameResolver，它根据 URL 样式解析方法名。</p>
<p>　　在缺省的 BeanNameUrlHandlerMapping 和缺省的 InternalPathMethodNameResolver 协调之下，Bean 上下文可以这样配置：</p>
<p>&lt;bean name="/updateUser.html" class="com.unmi.UserController"/&gt;　<br />
&lt;bean name="/deleteUser.html" class="com.unmi.UserController"/&gt;　</p>
<p>　　这样分别通过下面的 URL 就能执行到正确的方法上去了：</p>
<p>　　http://.../updateUser.html　--　将被 UserController.updateUser() 处理</p>
<p>　　http://.../deleteUser.html　 --　 将被 UserController.deleteUser() 处理</p>
<p>　　但是，你应该注意到了，上面的 com.unmi.UserController 配置了两次，一来碍眼、二来原来只要 Singleton 的 UserController 实例不再是那么回事了。<br />
所以要引入 SimpleUrlHandlerMapping 对 Bean 配置进一步紧凑一下：</p>
<p>&lt;bean id="userController" class="com.unmi.UserController"/&gt;　<br />
&lt;bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt;　<br />
　　&lt;property name="mappings"&gt;　<br />
　　　　&lt;props&gt;　<br />
　　　　　　&lt;prop key="/updateUser.html"&gt;userController&lt;/prop&gt;　<br />
　　　　　　&lt;prop key="/deleteUser.html"&gt;userController&lt;/prop&gt;　<br />
　　　　&lt;/props&gt;　<br />
　　&lt;/property&gt;　<br />
&lt;/bean&gt;　</p>
<p><br />
说是紧凑，倒不如说 Bean 配置复杂了，反正不用配置两个相同的 UserController 实例了。还是通过上面那两个 URL 来访问执行到相应的方法。</p>
<p>　　除了缺省的方法名解析器 InternalPathMethodNameResolver(注意了，Spring 中缺省的 XXX 很多用 InternalXXX 的命名)，还有两种其他类型的方法名解析器：</p>
<p>　　&#183;ParameterMethodNameResolver -- 根据请求中的参数解析执行方法名，相当于 Struts 的 DispathAction</p>
<p>　　&#183;PropertiesMethodNameResolver -- 根据查询一个 key/value 列表解析执行方法名，相当于 Struts 的 MappingDispatchAction(用得很少)</p>
<p>　　下面逐一介绍使用上面两种方法名解析器时的 Bean 配置及相应访问的 URL。</p>
<p>&nbsp;使用 ParameterMethodNameResolver 时的 Bean 配置(为简单起见，又用回了缺省的 HandlerMapping)：</p>
<p>&lt;bean name="/user.html" class="com.unmi.UserController"&gt;<br />
　&lt;property name="methodNameResolver"&gt;<br />
　&lt;ref bean="methodNameResolver"/&gt;<br />
　&lt;/property&gt;<br />
&lt;/bean&gt;<br />
&lt;bean name="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver"&gt;<br />
　&lt;property name="paramName"&gt;<br />
　&lt;value&gt;method&lt;/value&gt;<br />
　&lt;/property&gt;<br />
&lt;/bean&gt;<br />
这时候分别用下面的 URL 就能访问到相应的方法</p>
<p>　　http://.../user.html?method=updateUser -- 将被 UserController.updateUser() 处理</p>
<p>　　http://.../user.html?method=deleteUser　-- 将被 UserController.deleteUser() 处理</p>
<p>&nbsp;通过参数的方式使得 HTML 表单表现用户选择成为可能，例如把 method 参数可放在一个下拉框或隐藏域中。</p>
<p>　　使用 PropertiesMethodNameResolver 时的 Bean 配置</p>
<p>&lt;bean id="userController" class="com.unmi.UserController" /&gt;　<br />
&lt;bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"&gt;　<br />
　　&lt;property name="mappings"&gt;　<br />
　　　　&lt;props&gt;　<br />
　　　　　　&lt;prop key="/updateUser.html"&gt;userController&lt;/prop&gt;　<br />
　　　　　　&lt;prop key="/deleteUser.html"&gt;userController&lt;/prop&gt;　<br />
　　　　&lt;/props&gt;　<br />
　　&lt;/property&gt;　<br />
&lt;/bean&gt;　<br />
&lt;bean id="methodNameResolver"　 class="org.springframework.web.servlet.mvc.multiaction.PropertiesMethodNameResolver"&gt;　<br />
　　&lt;property name="mappings"&gt;　<br />
　　　　&lt;props&gt;　<br />
　　　　　　&lt;prop key="/updateUser.html"&gt;updateUser&lt;/prop&gt;　<br />
　　　　　　&lt;prop key="/deleteUser.html"&gt;deleteUser&lt;/prop&gt;　<br />
　　　　&lt;/props&gt;　<br />
　　&lt;/property&gt;　<br />
&lt;/bean&gt;　</p>
<p>&nbsp;这种配置有点复杂，PropertiesMethodNameResolver 不仅与 SimpleUrlHandlerMapping 相仿又有重叠，而且必须把 SimpleUrlHandlerMapping　拉进来，<br />
&nbsp;无法使用默认的 HandlerMapping。从上面的配置我们可以明显的看出 HandlerMapping 和 MethodNameResolver 不同职责了，一个是定位 Controller，<br />
&nbsp;一个是定位 Method。</p>
<p>　　这时候分别用下面的 URL 来访问到相应 Controller 的方法</p>
<p>　　http://.../updateUser.html　--　将被 UserController.updateUser() 处理</p>
<p>　　http://.../deleteUser.html　 --　 将被 UserController.deleteUser() 处理</p>
<p>　　这里的 URL 恰巧和使用 InternalPathMethodNameResolver　时是一样的，但一定要理解其实他们的机制是一样的。</p>
<p>　　PropertiesMethodNameResolver 把事性搞这么复杂，被誉为最复杂的方法名解析器。可我还真看不出它还有什么独到之处，或值得一用的理由，<br />
同时也不难理解 Struts 的 MappingDispatchAction 鲜为人知的缘由了。</p>
<img src ="http://www.blogjava.net/wuhen86/aggbug/288966.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2009-07-29 22:04 <a href="http://www.blogjava.net/wuhen86/articles/288966.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Spring中配置log4j</title><link>http://www.blogjava.net/wuhen86/articles/288960.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Wed, 29 Jul 2009 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/288960.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/288960.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/288960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/288960.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/288960.html</trackback:ping><description><![CDATA[导入Spring web lib <br />
spring-web.jar<br />
<br />
----------------------------------------------------------------------------------------------------<br />
首先需要在web.xml进行声明：<br />
<br />
&lt;!--如果不定义appRoot参数，那么appRoot就是缺省的"webapp.root"--&gt;<br />
&lt;context-param&gt;<br />
&lt;param-name&gt;appRoot&lt;/param-name&gt;<br />
&lt;param-value&gt;demo.root&lt;/param-value&gt;<br />
&lt;/context-param&gt;<br />
<br />
这里的demo是http://localhost:8080/demo/<br />
<br />
而root是系统开发目录中demo/root<br />
<br />
这样配置文件以及日志文件可以在spring的帮助下，放到开发环境中的任意位置<br />
<br />
&lt;!--由Sprng载入的Log4j配置文件位置--&gt;<br />
&lt;context-param&gt;<br />
&lt;param-name&gt;log4jConfigLocation&lt;/param-name&gt;<br />
&lt;param-value&gt;/WEB-INF/log4j.properties&lt;/param-value&gt;<br />
&lt;/context-param&gt;<br />
<br />
在这里定位配置文件，需要的是从root开始的绝对路径<br />
<br />
&lt;!--Spring默认刷新Log4j配置文件的间隔,单位为millisecond--&gt;<br />
&lt;context-param&gt;<br />
&lt;param-name&gt;log4jRefreshInterval&lt;/param-name&gt;<br />
&lt;param-value&gt;60000&lt;/param-value&gt;<br />
&lt;/context-param&gt;<br />
<br />
&lt;!--Spring log4j Config loader--&gt;<br />
&lt;listener&gt;<br />
&lt;listener-class&gt;org.springframework.web.util.Log4jConfigListener&lt;/listener-class&gt;<br />
&lt;/listener&gt;<br />
<br />
设置监听器<br />
<br />
<br />
log4j.properties<br />
<br />
#先设置级别<br />
log4j.rootCategory=INFO, file<br />
log4j.appender.file=org.apache.log4j.RollingFileAppender<br />
#在这里设置日志需要存放的位置，这里的变量就是我们在web.xml里设置的<br />
log4j.appender.file.File=${demo.root}/WEB-INF/logs/demo.log<br />
log4j.appender.file.MaxFileSize=100KB<br />
log4j.appender.file.MaxBackupIndex=0<br />
log4j.appender.file.layout=org.apache.log4j.SimpleLayout<br />
log4j.appender.file.layout.ConversionPattern=[ssh] %p %t %c - %m%n<br />
<br />
有了上面的配置，我们就可以查看日志了<br />
<img src ="http://www.blogjava.net/wuhen86/aggbug/288960.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2009-07-29 21:51 <a href="http://www.blogjava.net/wuhen86/articles/288960.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>