﻿<?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-Jhonney的专栏-随笔分类-转载区</title><link>http://www.blogjava.net/Jhonney/category/21574.html</link><description>&amp;nbsp;&amp;nbsp;&amp;nbsp;----得一人心，白头不相离</description><language>zh-cn</language><lastBuildDate>Sun, 22 Jul 2007 17:29:58 GMT</lastBuildDate><pubDate>Sun, 22 Jul 2007 17:29:58 GMT</pubDate><ttl>60</ttl><item><title>【转】你的核心竞争力是什么？</title><link>http://www.blogjava.net/Jhonney/archive/2007/07/22/131734.html</link><dc:creator>Jhonney</dc:creator><author>Jhonney</author><pubDate>Sun, 22 Jul 2007 08:42:00 GMT</pubDate><guid>http://www.blogjava.net/Jhonney/archive/2007/07/22/131734.html</guid><wfw:comment>http://www.blogjava.net/Jhonney/comments/131734.html</wfw:comment><comments>http://www.blogjava.net/Jhonney/archive/2007/07/22/131734.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Jhonney/comments/commentRss/131734.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Jhonney/services/trackbacks/131734.html</trackback:ping><description><![CDATA[　&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;早几天收到一位朋友发来的邮件，涉及到个人核心竞争力问题。朋友说，自己在学校的学习成绩比较好，具有竞争力。可是现在其他同学都具有了核心竞争力，而自己现在的工作&#8220;<span style="COLOR: #000000">随时找个人，很容易就能替换</span>&#8221;，因此，自己没有核心竞争力了。
<div style="COLOR: #000000">&nbsp;</div>
<div style="COLOR: #000000">　　这位朋友大学毕业两年，同学中有部分人从事软件开发，而我这位朋友选择了在互联网行业发展，目前的职位是一个中型网站的编辑部经理。朋友的同学中有个学Java的，写了2年程序，就自己开始招生搞培训班。于是，朋友就开始担心自己的竞争力问题了。</div>
<div style="COLOR: #000000">　</div>
<div>　　那么，什么是个人核心竞争力呢？所谓个人核心竞争力，就是指不断提高自己核心能力的能力。<span style="BACKGROUND-COLOR: yellow">所谓核心能力，是相对其他人而言的，这种能力能很好的实现自己在某方面的价值，且别人不容易模仿。</span>核心竞争力<span style="COLOR: red">不仅表现在所掌握的技术上，更重要的体现在所具有的独到思想或见解、对某个领域业务的综合把握</span>。</div>
<br>
<div>　　说到底，技术是不值钱的，只有业务和市场才能为企业赢利，技术只是实现业务的一个工具而已。因此，一个人要想具有核心竞争力，就必须对所在行业、所在企业的业务有深刻的理解，这远远不是学一两门程序设计语言就能搞定的事情。例如，朋友的同学搞Java培训班，其核心竞争力就是对IT培训业务的理解和洞察，而不是其Java程序设计的能力。（即使是Java程序设计能力，只毕业2年的学生，能核心到哪里去呢？如果有10年8年的经验，还说得过去！）如果其缺乏对培训业务的理解，缺乏培训公司运作的经验，其生存将是十分艰难的，倒闭就是眼前的事情。</div>
<br>
<div>　　个人核心竞争力其实是一个相对的概念，我们只能说某个人在某个方面具有核心竞争力，而不能笼统说甲具有核心竞争力，乙不具有核心竞争力。比如，拿大学教师为例，中文系的老师中会出名教授（具有核心竞争力），数学系的老师中也会出名教授（也具有核心竞争力）。但是，如果把中文系的名教授分配到数学系去上数学课，他就没有竞争力了。</div>
<div><br>　　我认为，对于软件开发人员而言，掌握一门程序设计语言并非是核心竞争力，而只是入门的一个工具而已，<strong style="COLOR: #ffffff; BACKGROUND-COLOR: #ff0000">能够利用这个工具熟悉某个行业的业务流程和运作方式，能够娴熟地利用这个工具为某个行业提供解决方案，这才是核心竞争力</strong>；对于从事互联网行业的人员而言，能够把网络流量变成现金流量，能够把网络平台与单位业务结合起来，能够洞察互联网的发展方向，这才是核心竞争力；<span style="COLOR: #ffffff; BACKGROUND-COLOR: #ff0000"><strong>对于管理人员，能够在有限的资源下，提高整个团队的战斗力和凝聚力，使团队紧密团结在自己的周围，向团队目标努力奋进，这才是核心竞争力。</strong></span></div>
<br>
<div>　　因此，就个人核心竞争力而言，行业不分好坏，职业不分好坏，工作不分好坏。只要你是有心人，在本职工作中潜心工作，努力摸索。这样，你收获的将不仅仅是每个月的工资，而且随着时间的增长，你的能力将不断提高，对业务的理解和把握能力将不断加强，最终形成自己的核心竞争力。<br><br>---------------------------------------------------------------------------------------<br>总结于一点，将自己的技能无论采用什么办法一定要达到和市场直接相结合<br></div>
<img src ="http://www.blogjava.net/Jhonney/aggbug/131734.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Jhonney/" target="_blank">Jhonney</a> 2007-07-22 16:42 <a href="http://www.blogjava.net/Jhonney/archive/2007/07/22/131734.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Message-Driven POJOs </title><link>http://www.blogjava.net/Jhonney/archive/2007/06/20/125227.html</link><dc:creator>Jhonney</dc:creator><author>Jhonney</author><pubDate>Tue, 19 Jun 2007 18:25:00 GMT</pubDate><guid>http://www.blogjava.net/Jhonney/archive/2007/06/20/125227.html</guid><wfw:comment>http://www.blogjava.net/Jhonney/comments/125227.html</wfw:comment><comments>http://www.blogjava.net/Jhonney/archive/2007/06/20/125227.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Jhonney/comments/commentRss/125227.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Jhonney/services/trackbacks/125227.html</trackback:ping><description><![CDATA[<p><a id=message_driven_pojos name=message_driven_pojos></a><a href="http://jroller.com/page/habuma/20050715#message_driven_pojos"><u><font color=#800080>http://jroller.com/page/habuma/20050715#message_driven_pojos</font></u></a><br><strong><br>Message-Driven POJOs</strong>
<p>In my preparation for a presentation I'll be giving next month, I have been tinkering with <a href="http://activemq.org/JCA+Container"><font color=#cc6633><u>Message-driven POJOs</u></font></a> as proposed by <a href="http://radio.weblogs.com/0112098/"><font color=#cc6633><u>James Strachan</u></font></a> and as implemented in <a href="http://activemq.codehaus.org/"><font color=#cc6633><u>ActiveMQ</u></font></a>.</p>
<p>Message-driven POJOs offer MDB-like functionality to simple JavaBeans. I have found message-driven POJOs to be a compelling alternative to MDBs, especially if you're already a big fan of <a href="http://www.springframework.org/"><font color=#cc6633><u>Spring</u></font></a> and are using it to develop your applications. Message-driven POJOs can take advantage of all of the features provided by Spring (such as dependency injection and AOP).</p>
<p>Although message-driven POJOs aren't exactly new news, I had a hard time finding much information about them online. ActiveMQ's own documentation isn't too bad, but left me with several unanswered questions. As a service to everyone out there who may be searching for more info on message-driven POJOs, I'm writing this article to document what I've learned. I hope you find it useful and maybe it will fill in some of the gaps for you.</p>
<h3>What you'll need</h3>
<p>To get started, here's a summary of the JARs that I used when developing and running the examples:</p>
<ul>
    <li>activemq-core-3.1-SNAPSHOT.jar
    <li>activemq-container-3.1-SNAPSHOT.jar
    <li>activemq-ra-3.1-SNAPSHOT.jar
    <li>commons-logging-1.0.3.jar
    <li>concurrent-1.3.4.jar
    <li>geronimo-spec-j2ee-connector-1.5-rc4.jar (or equivalent J2EE JAR)
    <li>geronimo-spec-j2ee-management-1.0-rc4.jar (or equivalent J2EE JAR)
    <li>geronimo-spec-jms-1.1-rc4.jar (or equivalent J2EE JAR)
    <li>geronimo-spec-jta-1.0.1B-rc4.jar (or equivalent J2EE JAR)
    <li>log4j-1.2.9.jar
    <li>spring.jar (version 1.2.2) </li>
</ul>
<p>The biggest challenge you'll face when developing message-driven POJOs is pulling together all of these JARs. To make things easier on you, I've made everything you'll need (including the example code) available <a href="http://www.habuma.com/sia/mdpojo.zip"><font color=#cc6633><u>here</u></font></a>.
<p>Your mileage may vary if you choose to use different versions of JARs than what I've listed above. One important note, however, is that in my examples, I'm using the shorthand XML available in Spring 1.2, so if you use an older version of Spring, you'll need to tweak the XML appropriately.</p>
<h3>Writing the message-driven POJO</h3>
<p>Writing a message-driven POJO isn't dramatically different than writing a message-driven EJB. The major difference is that you don't have to implement <code>javax.ejb.MessageDrivenBean</code>, which means that you also don't have to implement the EJB lifecycle methods mandated by that interface. (If you need to hook into a POJO's lifecycle, you can use Spring's <code>init-method</code> and <code>destroy-method</code> attributes when declaring the bean.)</p>
<p>In the interest of keeping the focus on how to develop message-driven POJOs, my example will be as simple as possible. In the grand tradition of all simple examples, here's a "Hello World" message-driven POJO:</p>
<code>&nbsp;&nbsp;package com.habuma.mdpojo;<br><br>&nbsp;&nbsp;import javax.jms.JMSException;<br>&nbsp;&nbsp;import javax.jms.Message;<br>&nbsp;&nbsp;import javax.jms.MessageListener;<br><br>&nbsp;&nbsp;public class HelloBean implements MessageListener {<br>&nbsp;&nbsp;&nbsp;&nbsp;public void onMessage(Message msg) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String name = msg.getStringProperty("name");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(name == null) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;name = "World";<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println("Hello " + name + "!");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} catch (JMSException e) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// handle exception?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;} </code>
<p>Notice that (as with MDBs) message-driven POJOs still must implement <code>javax.jms.MessageListener</code>. Even though James Strachan refers to these as POJOs, I don't consider this a pure POJO because in order to work it must implement a platform/framework-specific interface. But the <code>MessageListener</code> interface isn't too much of a burden to bear and it's still lighterweight than MDBs, so I guess I can't complain too much.</p>
<p>The <code>onMessage()</code> method should be self-explanatory. When a message is dispatched to this bean, this method is called. Inside of the method, we extract the "name" property from the message and use it to display the traditional greeting.</p>
<h3>Listening for messages</h3>
<p>The next thing to do is to declare <code>HelloBean</code> as a bean in a Spring context and associate it with a message queue. Declaring the bean itself is simple enough (in hello-mdpojo.xml):</p>
<code>&nbsp;&nbsp;&lt;bean id="helloBean" class="com.habuma.mdpojo.HelloBean"/&gt; </code>
<p>There's really nothing special about this bean. In a real application, however, your message-driven POJO would probably be more interesting and be injected with references to DAOs, service-layer beans, or some other beans that it collaborates with to do its job. It may also be proxied by some Spring aspects for declarative transactions, security, etc.</p>
<p>To associate "helloBean" with a message queue, we'll need to use ActiveMQ's <code>JCAContainer</code>. The <code>JCAContainer</code> associates itself with a specific ActiveMQ server and acts as a factory to produce connectors to that server. It is declared in Spring as a <code>&lt;bean&gt;</code>:</p>
<code>&nbsp;&nbsp;&lt;bean id="activeMQContainer" class="org.activemq.jca.JCAContainer"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="workManager"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id="workManager" class="org.activemq.work.SpringWorkManager"/&gt; <br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="resourceAdapter"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean id="activeMQResourceAdapter" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.activemq.ra.ActiveMQResourceAdapter"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="serverUrl" value="tcp://localhost:61616"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&lt;/bean&gt; </code>
<p>For the most part, this chunk of XML is boiler-plate code to set up a <code>JCAContainer</code> to interact with the message queue. The good news is that you'll only need one <code>JCAContainer</code>, regardless of how many of your POJOs will be message-driven.</p>
<p>The only thing of interest is the value assigned to the "serverUrl" property of the "activeMQResourceAdapter" inner-bean. This property tells the container how to connect to your ActiveMQ server--in this case, via TCP on port 61616 of the localhost (where ActiveMQ will be listening by default.)</p>
<p>At this point we have a <code>JCAContainer</code> that is associated with the ActiveMQ server and we have a POJO that is ready and willing to accept messages. All that's left is to connect the POJO to the <code>JCAContainer</code>. The following <code>&lt;bean&gt;</code> does the trick:</p>
<code>&nbsp;&nbsp;&lt;bean id="HelloMDP" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory-method="addConnector" <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;factory-bean="activeMQContainer"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="activationSpec"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;bean class="org.activemq.ra.ActiveMQActivationSpec"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="destination" value="Hello.Queue"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="destinationType" value="javax.jms.Queue"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/bean&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/property&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="ref" value="helloBean" /&gt; <br>&nbsp;&nbsp;&lt;/bean&gt; </code>
<p>This bean is where the proverbial "rubber meets the road". Using Spring's <code>factory-method</code> feature, this bean declaration leans on the <code>JCAContainer</code>'s <code>addConnector()</code> method to create a connector to associate the "helloBean" with the ActiveMQ server. Specifically, the "activationSpec" property tells the <code>JCAContainer</code> to set up a connector that listens to the queue named "Hello.Queue" and the "ref" property tells it to send messages from that queue to the bean named "helloBean".</p>
<p>Bringing this message-driven POJO to life requires two things. First, you'll need to fire up an ActiveMQ server. In the bin directory of the ActiveMQ distribution, you'll find either an activemq.bat (for Windows) or an activemq script (for UNIX). Running this script will start up an ActiveMQ server instance listening on port 61616.</p>
<p>The next thing you'll need is a simple application that loads the Spring application context. The following <code>main()</code> method should suffice (I'll leave the class you place this in up to you):</p>
<code>&nbsp;&nbsp;public static void main(String[] args) {<br>&nbsp;&nbsp;&nbsp;&nbsp;new FileSystemXmlApplicationContext("hello-mdpojo.xml");<br>&nbsp;&nbsp;} </code>
<p>If all goes well, running this program will result in a <code>HelloBean</code> POJO that is patiently awaiting a message to process. So, let's send it a message.</p>
<h3>Sending a message</h3>
<p>There are a variety of ways to send a JMS message, but for the purposes of this example, I'm going to use Spring's JmsTemplate (as described in chapter 7 of <a href="http://www.amazon.com/exec/obidos/ASIN/1932394354/habumacom-20"><em><font color=#cc6633><u>Spring in Action</u></font></em></a>). The following declaration of a JmsTemplate is what I used to test the <code>HelloBean</code> (in mq-client.xml):</p>
<code>&nbsp;&nbsp;&lt;bean id="jmsTemplate"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.springframework.jms.core.JmsTemplate"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="defaultDestinationName" value="Hello.Queue"/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="connectionFactory" ref="connectionFactory"/&gt;<br>&nbsp;&nbsp;&lt;/bean&gt; </code>
<p>The "defaultDestinationName" property tells the template the name of the message queue to attach to. The "connectionFactory" property tells the template how to connect. I could've used Spring's JndiObjectFactoryBean to pull a connection factory from JNDI (as I described in SiA) or any implementation of javax.jms.ConnectionFactory. But so that I don't have to mess with JNDI for this simple example, let's use ActiveMQ's ActiveMQConnectionFactory:</p>
<code>&nbsp;&nbsp;&lt;bean id="connectionFactory"<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;class="org.activemq.ActiveMQConnectionFactory"&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&lt;property name="brokerURL" value="tcp://localhost:61616" /&gt;<br>&nbsp;&nbsp;&lt;/bean&gt; </code>
<p>Now we just need to use the "jmsTemplate" bean to send a message. In a real application, you might inject "jmsTemplate" into a property of another bean to use. But for simplicity's sake we'll just access the bean directly from a <code>main()</code> method (again, I'll leave the choice of a class up to you):</p>
<code>&nbsp;&nbsp;public static void main(String[] args) {<br>&nbsp;&nbsp;&nbsp;&nbsp;ApplicationContext ctx = new<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FileSystemXmlApplicationContext("mq-client.xml");<br><br>&nbsp;&nbsp;&nbsp;&nbsp;JmsTemplate template = (JmsTemplate) ctx.getBean("jmsTemplate");<br>&nbsp;&nbsp;&nbsp;&nbsp;template.send(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new MessageCreator() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public Message createMessage(Session session)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;throws JMSException {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MapMessage message = session.createMapMessage();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message.setStringProperty("name", "Craig");<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return message;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;);<br>&nbsp;&nbsp;} </code>
<p>Run this program in a separate window from where the application that runs the <code>JCAContainer</code>. If things are going your way, you should see "Hello Craig!" in the window running the <code>JCAContainer</code> app. Congratulations, you've just invoked a message-driven POJO.</p>
<h3>So what?</h3>
<p>What's the big deal? Why are message-driven POJOs better than MDBs? Well, I never actually claimed any superiority of message-driven POJOs over MDBs. But here are some things to consider:</p>
<ul>
    <li>MDBs must be run within an EJB container. Depending on the architecture of your app, this may be an excessive requirement, especially if you aren't use any other EJBs and do not require the features of a full-blown EJB container. Message-driven POJOs, on the other hand, can run anywhere, even (as shown here) in a simple main() method. The only requirement is an ActiveMQ message queue.
    <li>MDBs require that you implement the lifecycle methods of <code>javax.ejb.MessageDrivenBean</code>. Often these lifecycle methods aren't needed and are left as empty implementations. This isn't a real problem, except that it's simply unnecessary.
    <li>Although it may not be apparent from the simple <code>HelloBean</code> example, message-driven POJOs can take full advantage of the dependency injection and AOP support offered by Spring (including Spring's support for declarative transactions and Acegi's support for declarative security). In short, you can do anything with the POJO that you can do with any other bean in a Spring context.
    <li>The XML used to declare a message-driven POJO is slightly more verbose then for an MDB. You should, however, keep in mind that you'll only need to declare one <code>JCAContainer</code> bean, regardless of how many message-driven POJOs your application has. </li>
</ul>
<p>One thing that I've not yet considered is how EJB 3 MDBs compare the message-driven POJOs. Honestly, I've not taken the time to perform this comparison. Perhaps this is something I'll do soon. If you have any insight in this subject, I'd be quite interested in hearing it.</p>
<p>Message-driven POJOs are just a small portion of a talk that I'll be presenting at the <a href="http://www.nofluffjuststuff.com/show_view.jsp?showId=33"><font color=#cc6633><u>LoneStar Software Symposium</u></font></a> in Austin, TX next month. If you're in the Austin area, I hope to see you there.</p>
<img src ="http://www.blogjava.net/Jhonney/aggbug/125227.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Jhonney/" target="_blank">Jhonney</a> 2007-06-20 02:25 <a href="http://www.blogjava.net/Jhonney/archive/2007/06/20/125227.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Limit指南</title><link>http://www.blogjava.net/Jhonney/archive/2007/06/12/123717.html</link><dc:creator>Jhonney</dc:creator><author>Jhonney</author><pubDate>Tue, 12 Jun 2007 13:28:00 GMT</pubDate><guid>http://www.blogjava.net/Jhonney/archive/2007/06/12/123717.html</guid><wfw:comment>http://www.blogjava.net/Jhonney/comments/123717.html</wfw:comment><comments>http://www.blogjava.net/Jhonney/archive/2007/06/12/123717.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Jhonney/comments/commentRss/123717.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Jhonney/services/trackbacks/123717.html</trackback:ping><description><![CDATA[<p>quto:http://www.blogjava.net/lucky/archive/2006/02/23/32059.html<br><br></p>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h2 class=title style="CLEAR: both"><a name=d0e4></a>1.&nbsp;引言</h2>
</div>
</div>
</div>
<p>在你需要处理大量数据时你应该考虑使用eXtremeTable的Limit特性。Limit这个名字来自MySQL的limit 命令，Limit接口的目的就是如何对表的结果集进行limit处理。Limit实现知道当排序、过滤、分页、导出时，用户如何与表互相作用。有了这些信息你 将能够使用可能是最有效的方式显示正确的过滤、排序后的请求页面。</p>
<p>为了示范Limit特性，我将要做的工作将分解为JSP、Controller、Service和DAO。这示范了一种使用分层的方式来处理 Limit。你可以根据自己的需要来增加或减少层。本示例也使用了Spring框架来重新得到使用Spring的JDBC取得的数据，因此你的代码看起来可能有点不同。eXtremeTable的一个特点就是不依赖任何框架和容器。 </p>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=d0e11></a>1.1.&nbsp;JSP</h3>
</div>
</div>
</div>
<p>为了使用Limit特性，eXtremeTable需要使用limit特定的RetrieveRowsCallback、 FilterRowsCallback和SortRowsCallback接口。eXtremeComponents提供了每个接口的一个实现，可以简单地通过设置每个属性值为limit来简单来使用。 </p>
<pre class=programlisting>&lt;ec:table <br>   items="presidents"<br>   retrieveRowsCallback="limit"<br>   filterRowsCallback="limit"<br>   sortRowsCallback="limit"<br>   view="limit"<br>   &gt;<br>...</pre>
<p>另外视图属性参照一个名为limit的定制视图。这是一个简单修改默认eXtremeTable视图，不包含最后页工具条的实现。这仅仅关系到你是否能取得确切需要的行。 一些数据库例如Oracle和MySQL都提供了一种得到确定行的特性，但是，其他的数据库例如：Sybase没有提供特性。在我的示例中我考虑最坏的情况你的数据库不支持这种特性。</p>
<p>即使你的数据库不提供取得特定行的特性，当你考虑用户如何和表协同工作时，Limit仍然非常有意义。用户通常会对一些数据进行排序、过滤和分页。 这个例子中15条数据构成一页，第一页需要15条数据，第二页需要30条数据，第三页需要45条数据，以此类推。在经过一段时间分页后，他们常常使用过滤来提炼数据。 即使他们不这样做，他们也必须在此之前对大量的数据进行分页，这将影响效率。当然如果允许用户点击最后页，那么所有的数据都将被取出，这将非常影响效率。</p>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=d0e22></a>1.2.&nbsp;Controller</h3>
</div>
</div>
</div>
<p><span class=emphasis><em>提示：Spring框架的Controller和Struts框架的Action非常相像。</em></span> </p>
<p>controller首先需要创建一个Limit。为了完成这个你需要得到一些关于Context和LimitFactory的帮助。</p>
<pre class=programlisting>Context context = new HttpServletRequestContext(request);<br>LimitFactory limitFactory = new TableLimitFactory(context);<br>Limit limit = new TableLimit(limitFactory);</pre>
<p>Context是一个处理取得属性的接口，LimitFactory使用Context来找出用户如何和eXtremeTable交互。 然后Limit使用LimitFactory来组装自己。</p>
<p>为了初始化Limit，它将包含所有的有用的信息。这些信息包括数据将被如何排序和过滤，哪一页将被显示和是否允许被导出。</p>
<p>然而，Limit仍然需要得到行的信息，这样正确的信息页面才能被显示给用户。行信息包括开始行、结束行、当前显示行。 controller必须从service得到这些信息，而Service将从dao中得到这些信息。这里我只给出Controller端的代码。</p>
<pre class=programlisting>int totalRows = presidentsService.getTotalPresidents(limit.getFilterSet(), limit.isExported());<br>limit.setRowAttributes(totalRows, defaultRowsDisplayed);</pre>
<p>limit需要得到所有的行来得到行的信息。service需要知道那些被过滤，不管这些数据是否要导出。为了设置行信息，默认的一页显示的行数需要被设置。 这可以通过对TableTag的rowsDisplayed属性设置一个确定的数值来实现。</p>
<p>现在我们只需要从services得到Collection数据。</p>
<pre class=programlisting>Collection presidents = presidentsService.getPresidents(limit.getFilterSet(), limit.getSort(), limit.getRowEnd());</pre>
<p>因为limit已经包含所有信息，这将十分容易。所有需要做的就是传入过滤器，排序和最后行的信息。 最后要做的是将Collections和totalRow这些信息传送回JSP以便eXtremeTable知道如何显示这些信息。</p>
<pre class=programlisting>request.setAttribute("presidents", presidents);<br>request.setAttribute("totalRows", new Integer(totalRows));</pre>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=d0e52></a>1.3.&nbsp;Service</h3>
</div>
</div>
</div>
<p>service需要和dao进行交互来得到总行数和Collection。</p>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e57></a>1.3.1.&nbsp;取得总行数</h4>
</div>
</div>
</div>
<p>controller需要到第一条信息就是总行数。</p>
<pre class=programlisting>public int getTotalPresidents(FilterSet filterSet, boolean isExported) {<br>    String totalQuery = presidentsDao.getTotalPresidentsQuery();<br>    String modTotalQuery = filterQuery(filterSet, totalQuery);<br>    int totalRows = presidentsDao.getTotalPresidents(modTotalQuery);<br>    if (isExported &amp;&amp; totalRows &gt; maxExportRows) {<br>        totalRows = maxExportRows;<br>    }<br>    return totalRows;<br>}</pre>
<p>service和dao一起来过滤结果集，它的工作方式是在Where语句后面增加更多的AND语句来修改查询字符串。为此，你需要和Limit FilterSet一起工作。</p>
<p>FilterSet是一个过滤器对象数组，一个过滤器包括一个bean property和这个过滤器的值。或者，简单的说就是用户想要过滤的行和他们输入的值。这使得它非常容易交互。service只需要迭代所有的 FilterSet并调用dao来拼接查询语句。（译者注：过滤的实现方式是：在Where后面增加And语句来改变查询语句以达到对数据进行过滤的效果）</p>
<pre class=programlisting>private String filterQuery(FilterSet filterSet, String query) {<br>    if (!filterSet.isFiltered() || filterSet.isCleared()) {<br>        return query;<br>    }<br>    <br>    Filter filters[] = filterSet.getFilters();<br>    for (int i = 0; i &lt; filters.length; i++) {<br>        Filter filter = filters[i];<br>        String property = filter.getProperty();<br>        String value = filter.getValue();<br>        query = presidentsDao.filterQuery(query, property, value);<br>    }<br><br>    return query;<br>}</pre>
<p>query修改包括了filter信息，总行数。在一些情况下这就足够，但是当用户导出数据时仍然存在一个潜在的问题。为了保持高效 service不允许导出超出一个最大行数的数据。</p>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e72></a>1.3.2.&nbsp;取得Collection</h4>
</div>
</div>
</div>
<p>controller需要到第二条信息就是Collection。</p>
<pre class=programlisting>public Collection getPresidents(FilterSet filterSet, Sort sort, int rowEnd) {<br>    String patientsQuery = presidentsDao.getPresidentsQuery();<br>    String modPatientsQuery = filterQuery(filterSet, patientsQuery);<br>    modPatientsQuery = sortQuery(sort, modPatientsQuery);<br>    modPatientsQuery = presidentsDao.limitQuery(rowEnd, modPatientsQuery);<br>    return presidentsDao.getPresidents(modPatientsQuery);<br>}</pre>
<p>和前面一样，service和dao一起来过滤结果集。</p>
<p>另外query字符串需要扩展ORDER BY语句以便数据按照正确的方式进行排序。Sort包含一个bean property和 sortOrder值（正序还是逆序）。service仅仅需要使用Sort来调用dao。</p>
<pre class=programlisting>private String sortQuery(Sort sort, String query) {<br>    if (!sort.isSorted()) {<br>        String defaultSortOrder = presidentsDao.getDefaultSortOrder();<br>        if (StringUtils.isNotBlank(defaultSortOrder)) {<br>            return query + defaultSortOrder;<br>        }<br>        <br>        return query;<br>    }<br><br>    String property = sort.getProperty();<br>    String sortOrder = sort.getSortOrder();<br>    <br>    return presidentsDao.sortQuery(query, property, sortOrder);<br>}<br></pre>
<p>query字符串最后需要的修改就是增加数据库特别的指令来limit将要被返回的结果集。这就是limitQuery() 方法的作用。</p>
</div>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h3 class=title><a name=d0e87></a>1.4.&nbsp;DAO</h3>
</div>
</div>
</div>
<p>dao为service负责底层数据工作。</p>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e92></a>1.4.1.&nbsp;定义Query字符串</h4>
</div>
</div>
</div>
<p>为了真正理解dao，query字符串需要被展示。</p>
<p>这就是得到数据的presidents query字符串：</p>
<pre class=programlisting>private final static String presidentsQuery = <br>        " SELECT " +<br>        "    president_id presidentId, " + <br>        "    first_name firstName, " +<br>        "    last_name lastName, " +<br>        "    nick_name nickName,  " +<br>        "    concat(first_name, ' ',last_name) fullName, " +<br>        "    term,  " +<br>        "    born,  " +<br>        "    died,  " +<br>        "    education, " + <br>        "    career,  " +<br>        "    political_party politicalParty " +<br>        " FROM presidents ";</pre>
<p>这是得到总行数的query字符串：</p>
<pre class=programlisting>private final static String totalPresidentsQuery = <br>        " SELECT count(*) FROM presidents ";</pre>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e105></a>1.4.2.&nbsp;Filter 和 Sort Query 字符串</h4>
</div>
</div>
</div>
<p>两个最有趣的方法就是过滤和排序。</p>
<p>filter看起来像这样：</p>
<pre class=programlisting>public String filterQuery(String query, String property, String value) {<br>    StringBuffer result = new StringBuffer(query);<br><br>    if (query.indexOf("WHERE") == -1) {<br>        result.append(" WHERE 1 = 1 "); //stub WHERE clause so can just append AND clause<br>    }<br>        <br>    if (property.equals("fullName")) {<br>        result.append(" AND concat(first_name, ' ',last_name) like '%" + value + "%'");<br>    } else if (property.equals("nickName")) {<br>        result.append(" AND nick_name like '%" + value + "%'");<br>    } else {<br>        result.append(" AND " + property + " like '%" + value + "%'");<br>    }<br>        <br>    return result.toString();<br>}</pre>
<p>filterQuery()方法需要增加正确的AND语句到query字符串。</p>
<p>sort看起来非常类似：</p>
<pre class=programlisting>public String sortQuery(String query, String property, String sortOrder) {<br>    StringBuffer result = new StringBuffer(query + " ORDER BY ");<br>        <br>    if (property.equals("fullName")) {<br>        result.append("concat(first_name, ' ',last_name) " + sortOrder);<br>    } else {<br>        result.append(property + " " + sortOrder);<br>    }<br><br>    return result.toString();<br>}</pre>
<p>sortQuery()方法需要增加正确的ORDER BY语句到query字符串。</p>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e122></a>1.4.3.&nbsp;Limit Query String</h4>
</div>
</div>
</div>
<p>现在query字符串修改能够正确的进行filter和sort，它还需要修改以便只取页面显示相关的数据。MySQL为s the limit命令。</p>
<pre class=programlisting>public String limitQuery(int rowEnd, String query) {<br>    return query + " limit " + rowEnd;<br>}</pre>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e129></a>1.4.4.&nbsp;取回总行数和Collection.</h4>
</div>
</div>
</div>
<p>service需要的唯一东西就是：总行数和Collection。</p>
<pre class=programlisting>public Collection getPresidents(final String query) {<br>    return jdbcTemplate.query(query, new ResultReader() {<br>        List results = new ArrayList();<br>         public List getResults() {<br>            return results;<br>        }<br><br>        public void processRow(ResultSet rs)<br>                throws SQLException {<br>            President president = new President();<br>            president.setPresidentId(new Integer(rs.getInt("presidentId")));<br>            president.setFirstName(rs.getString("firstName"));<br>            president.setLastName(rs.getString("lastName"));<br>            president.setNickName(rs.getString("nickName"));<br>            president.setFullName(rs.getString("fullName"));<br>            president.setTerm(rs.getString("term"));<br>            president.setBorn(rs.getDate("born"));<br>            president.setDied(rs.getDate("died"));<br>            president.setEducation(rs.getString("education"));<br>            president.setCareer(rs.getString("career"));<br>            president.setPoliticalParty(rs.getString("politicalParty"));<br>            results.add(president);<br>        }<br>    });        <br>}<br><br>public int getTotalPresidents(final String query) {<br>    return jdbcTemplate.queryForInt(query);<br>}</pre>
<p>ResultReader是一个帮助处理JDBC查询的Spring特殊类，作为一个callback来处理JDBC ResultSet。jdbcTemplate是对JDBC连接的抽象。</p>
</div>
<div class=section lang=en>
<div class=titlepage>
<div>
<div>
<h4 class=title><a name=d0e138></a>1.4.5.&nbsp;默认的Sort顺序</h4>
</div>
</div>
</div>
<p>最后，这是service需要的默认sort顺序：</p>
<pre class=programlisting>public String getDefaultSortOrder() {<br>    return " ORDER BY concat(first_name, ' ', last_name) ";        <br>}</pre>
</div>
</div>
</div>
<img src ="http://www.blogjava.net/Jhonney/aggbug/123717.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Jhonney/" target="_blank">Jhonney</a> 2007-06-12 21:28 <a href="http://www.blogjava.net/Jhonney/archive/2007/06/12/123717.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>rowset下载地址</title><link>http://www.blogjava.net/Jhonney/archive/2007/06/08/122830.html</link><dc:creator>Jhonney</dc:creator><author>Jhonney</author><pubDate>Fri, 08 Jun 2007 05:23:00 GMT</pubDate><guid>http://www.blogjava.net/Jhonney/archive/2007/06/08/122830.html</guid><wfw:comment>http://www.blogjava.net/Jhonney/comments/122830.html</wfw:comment><comments>http://www.blogjava.net/Jhonney/archive/2007/06/08/122830.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Jhonney/comments/commentRss/122830.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Jhonney/services/trackbacks/122830.html</trackback:ping><description><![CDATA[<p><br><a href="http://java.sun.com/products/jdbc/download.html#rowsetcobundle1_0">http://java.sun.com/products/jdbc/download.html#rowsetcobundle1_0<br></a>//////////////////////////////////<br></p>
<div class=postTitle><a href="http://blog.csdn.net/zynovo/archive/2006/05/11/724904.aspx"><img height=13 src="http://blog.csdn.net/images/authorship.gif" width=15 border=0><u><font color=#4371a6>&nbsp;CachedRowSet使用的问题一则-rowset.jar在jdk1.4下的使用</font></u></a> </div>
<div class=postText>
<p>在使用rowset包的时候遇到了这样的问题：<br>java.lang.NullPointerException<br>at java.io.Reader.&lt;init&gt;(Reader.java:61)<br>at java.io.InputStreamReader.&lt;init&gt;(InputStreamReader.java:80)<br>at java.util.Properties.load(Properties.java:266)<br>at java.util.PropertyResourceBundle.&lt;init&gt;(PropertyResourceBundle.java:96)<br>at com.sun.rowset.JdbcRowSetResourceBundle.&lt;init&gt;(JdbcRowSetResourceBundle.java:92)<br>at com.sun.rowset.JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(JdbcRowSetResourceBundle.java:114)<br>at com.sun.rowset.CachedRowSetImpl.&lt;init&gt;(CachedRowSetImpl.java:360)Exception: null<br>at com.sun.rowset.WebRowSetImpl.&lt;init&gt;(WebRowSetImpl.java:68)<br>at test.Test.generateXML(Test.java:98)<br>at test.Test.main(Test.java:168)</p>
<p>在网上看了一篇《使用最新sun公司的rowset.jar包的请注意》的文章，用了感觉不太好使，又看了一下sun社区的那篇，里面有种方法，挺好用，也不用修改rowset包，我写了一个CachedRowSet生成类.把自己的代码贴出来，和大家分享。(不知道代码好使不好).</p>
<p>rowset.jar包可以在下面的连接页面下载</p>
<p><a href="http://java.sun.com/products/jdbc/download.html#rowsetcobundle1_0"><u><font color=#4371a6>http://java.sun.com/products/jdbc/download.html#rowsetcobundle1_0</font></u></a></p>
<p>import javax.sql.rowset.CachedRowSet;<br>import com.sun.rowset.CachedRowSetImpl;<br>import java.util.Locale;<br>import java.sql.*;</p>
<p>public class cachedRowsetCreater {<br>&nbsp; protected CachedRowSet crs=createCachedRowset();<br>&nbsp; public void close(){<br>&nbsp;&nbsp;&nbsp; try {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; crs.release();<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; catch (SQLException ex) {<br>&nbsp;&nbsp;&nbsp; }<br>&nbsp;&nbsp;&nbsp; crs=null;<br>&nbsp; }<br>&nbsp; public cachedRowsetCreater(String JNDI_NAME) throws Exception {<br>&nbsp;&nbsp;&nbsp; crs.setDataSourceName(JNDI_NAME);<br>}</p>
<p>&nbsp; public CachedRowSet createCachedRowset() throws SQLException<br>{<br>Locale locale = Locale.getDefault ();<br>try<br>{//设置资源为中国大陆<br>Locale.setDefault (Locale.CHINESE);//在linux下好像要用CHINA<br>return new CachedRowSetImpl ();<br>}<br>finally<br>{<br>Locale.setDefault (locale);<br>}<br>}<br>public CachedRowSet executeQuery(String QueryString){<br>&nbsp; try{<br>&nbsp; CachedRowSet crs1=crs.createCopySchema();<br>&nbsp; crs1.setCommand(QueryString);<br>&nbsp; crs1.execute();<br>&nbsp; return crs1;<br>}catch(SQLException e){<br>&nbsp; return null;<br>}<br>}</p>
<p>}<br></p>
</div>
<img src ="http://www.blogjava.net/Jhonney/aggbug/122830.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Jhonney/" target="_blank">Jhonney</a> 2007-06-08 13:23 <a href="http://www.blogjava.net/Jhonney/archive/2007/06/08/122830.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cvc-complex-type.2.4.a错误解决方法</title><link>http://www.blogjava.net/Jhonney/archive/2007/05/19/118546.html</link><dc:creator>Jhonney</dc:creator><author>Jhonney</author><pubDate>Sat, 19 May 2007 06:56:00 GMT</pubDate><guid>http://www.blogjava.net/Jhonney/archive/2007/05/19/118546.html</guid><wfw:comment>http://www.blogjava.net/Jhonney/comments/118546.html</wfw:comment><comments>http://www.blogjava.net/Jhonney/archive/2007/05/19/118546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Jhonney/comments/commentRss/118546.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Jhonney/services/trackbacks/118546.html</trackback:ping><description><![CDATA[<div class=cnt>&lt;jsp-config&gt;<br>&lt;taglib&gt;<br>&lt;taglib-uri&gt;/tags/struts-html&lt;/taglib-uri&gt;<br>&lt;taglib-location&gt;/WEB-INF/struts-html.tld&lt;/taglib-location&gt;<br>&lt;/taglib&gt;<br><br>&lt;taglib&gt;<br>　　&lt;taglib-uri&gt;/tags/struts-bean&lt;/taglib-uri&gt;<br>　　&lt;taglib-location&gt;/WEB-INF/struts-bean.tld&lt;/taglib-location&gt;<br>　　&lt;/taglib&gt;<br>　　<br>　　&lt;taglib&gt;<br>　　&lt;taglib-uri&gt;/tags/struts-logic&lt;/taglib-uri&gt;<br>　　&lt;taglib-location&gt;/WEB-INF/struts-logic.tld&lt;/taglib-location&gt;<br>　　&lt;/taglib&gt;<br>&lt;/jsp-config&gt;<br><strong>///////把所有跟jsp设置有关的内容都放在&lt;jsp-config&gt;&lt;/jsp-config&gt;里面////////</strong></div>
<img src ="http://www.blogjava.net/Jhonney/aggbug/118546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Jhonney/" target="_blank">Jhonney</a> 2007-05-19 14:56 <a href="http://www.blogjava.net/Jhonney/archive/2007/05/19/118546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>单例的实现</title><link>http://www.blogjava.net/Jhonney/archive/2007/04/12/110281.html</link><dc:creator>Jhonney</dc:creator><author>Jhonney</author><pubDate>Thu, 12 Apr 2007 13:55:00 GMT</pubDate><guid>http://www.blogjava.net/Jhonney/archive/2007/04/12/110281.html</guid><wfw:comment>http://www.blogjava.net/Jhonney/comments/110281.html</wfw:comment><comments>http://www.blogjava.net/Jhonney/archive/2007/04/12/110281.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/Jhonney/comments/commentRss/110281.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/Jhonney/services/trackbacks/110281.html</trackback:ping><description><![CDATA[public class Singleton {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; static class SingletonHolder {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; static Singleton instance = new Singleton();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; public static Singleton getInstance() {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; return SingletonHolder.instance;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp; <br>}&nbsp;&nbsp;&nbsp;<br>
<p>See in : <a href="http://crazybob.org/2007/01/lazy-loading-singletons.html" target=blank><u><font color=#800080>http://crazybob.org/2007/01/lazy-loading-singletons.html</font></u></a> <br>See also : <a href="http://www.oreillynet.com/onjava/blog/2007/01/singletons_and_lazy_loading.html" target=blank><u><font color=#0000ff>http://www.oreillynet.com/onjava/blog/2007/01/singletons_and_lazy_loading.html</font></u></a></p>
<img src ="http://www.blogjava.net/Jhonney/aggbug/110281.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/Jhonney/" target="_blank">Jhonney</a> 2007-04-12 21:55 <a href="http://www.blogjava.net/Jhonney/archive/2007/04/12/110281.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>