<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Live in code &#187; quickstart</title>
	<atom:link href="http://www.agatezone.cn/code/tag/quickstart/feed" rel="self" type="application/rss+xml" />
	<link>http://www.agatezone.cn/code</link>
	<description>agate&#039;s tech blog</description>
	<lastBuildDate>Tue, 20 Jul 2010 05:35:32 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>RMI 小例子</title>
		<link>http://www.agatezone.cn/code/archives/238</link>
		<comments>http://www.agatezone.cn/code/archives/238#comments</comments>
		<pubDate>Wed, 08 Oct 2008 11:45:02 +0000</pubDate>
		<dc:creator>agate</dc:creator>
				<category><![CDATA[程序编码]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[quickstart]]></category>
		<category><![CDATA[rmi]]></category>

		<guid isPermaLink="false">http://www.agatezone.cn/code/?p=238</guid>
		<description><![CDATA[今天帮朋友做课程设计, 要用 RMI 远端操控数据库. 于是乎便看了一下 RMI 应用的用法规则. 发现十分简单. 在这里写下一个 HelloWorld 例子, 以便未来参考.
引言: 白痴的我明明知道 RMI 底层是 Socket 实现的, 传递的对象固然要序列化. 但是今天我竟然傻逼地把 Connection 传导客户端操作... 小朋友不要学我变成白痴哦!
一. 结构(我叫他规则):
一个接口, 一个实现类. 一个服务器端, 一个客户端. 总共三类一接口.
二. 代码:

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Product extends Remote {
    public String getName() throws RemoteException;
}


import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ProductImpl extends UnicastRemoteObject implements Product {

    [...]]]></description>
			<content:encoded><![CDATA[<p>今天帮朋友做课程设计, 要用 RMI 远端操控数据库. 于是乎便看了一下 RMI 应用的用法规则. 发现十分简单. 在这里写下一个 HelloWorld 例子, 以便未来参考.</p>
<blockquote><p>引言: 白痴的我明明知道 RMI 底层是 Socket 实现的, 传递的对象固然要序列化. 但是今天我竟然傻逼地把 Connection 传导客户端操作... 小朋友不要学我变成白痴哦!</p></blockquote>
<p><strong>一. 结构(我叫他规则):</strong><br />
一个接口, 一个实现类. 一个服务器端, 一个客户端. 总共三类一接口.</p>
<p><strong>二. 代码:</strong></p>
<pre class="brush: java;">
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Product extends Remote {
    public String getName() throws RemoteException;
}
</pre>
<pre class="brush: java;">
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class ProductImpl extends UnicastRemoteObject implements Product {

    private String name;

    public ProductImpl(String name) throws RemoteException {
        this.name = name;
    }

    public String getName() throws RemoteException {
        System.out.println(&quot;方法 getName 被调用！&quot;);
        return name;
    }

}
</pre>
<pre class="brush: java;">
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Server {

    public static void main(String[] args) {
        try {
            Registry r = LocateRegistry.createRegistry(1099);
            Product p = new ProductImpl(&quot;乐事薯片&quot;); //我的最爱
            r.bind(&quot;p&quot;, p);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
</pre>
<pre class="brush: java;">
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {
public static void main(String[] args) {
        try {
            String host = &quot;&quot;; //这里替换成你的服务器地址, 空的就代表本机
            Registry r = LocateRegistry.getRegistry(host);
            Product p = (Product)r.lookup(&quot;p&quot;);
            System.out.println(&quot;此产品的名字为：&quot; + p.getName());
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
}
</pre>
<p><strong>三. 执行:</strong><br />
<em>1. 放置</em><br />
将上述 4 个类放置在统一文件夹下.<br />
<em>2. 编译</em><br />
<code>javac -cp . *.java</code><br />
<em>3. 启动服务器端</em><br />
启动一个终端, 进入该文件夹, 执行:<br />
<code>java -cp . Server</code><br />
<em>4. 启动客户端</em><br />
启动一个终端, 进入该文件夹, 执行:<br />
<code>java -cp . Client</code></p>
<p>四. 注意<br />
编码问题一直存在, java 编译也不例外! 在 Linux 这些 UTF-8 的世界里请大家把上面四个文件都保存成 UTF-8 格式. Windows 的世界里, 保存成 ANSI 即可!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.agatezone.cn/code/archives/238/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Spring AOP 起步</title>
		<link>http://www.agatezone.cn/code/archives/27</link>
		<comments>http://www.agatezone.cn/code/archives/27#comments</comments>
		<pubDate>Fri, 07 Dec 2007 13:41:08 +0000</pubDate>
		<dc:creator>agate</dc:creator>
				<category><![CDATA[程序编码]]></category>
		<category><![CDATA[aop]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[quickstart]]></category>
		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://www.agatezone.cn/code/?p=27</guid>
		<description><![CDATA[其实我的个人表达能力不是很好……估计小时候语文没学好～也可能是aop这个概念本身意会的程度很大吧！呵呵寒暄一下！
正式进入主题：AOP 即 Aspect Oriented Programming 的缩写，中文译为"面向切面编程"。本篇没那么学术化，只是为了快速入门了解真实的使用方式！我们不用那么早去想这个名词的意义，fellow me，用真实的代码透析AOP的含义。
不知各位有没有项目开发的经验，如果有的话你应该可以清楚地了解到我们的代码中常常充斥着大量的日志记录代码，我们用log4j等日志记录工具一段一段地记录程序运行的信息。也许有个别是十分特殊的，但是似乎大部分都是例行公事吧！或者在丢出exception的时候捕获其message然后记入日志对吗？这样的代码难道不觉得碍眼？修改起来是不是也很麻烦？要是我们换了一个日志记录工具怎么办？呵呵，别吓到了，没这么严重啦，这些都是极端情况，平时我们还是很开心地写着这些东西。但是今天要说到的这个aop可以将一些特别的操作提取出来，作为我们的"通知-advice"，在运行时加载到对象中。就是说，我们可以在代码中不写日志记录段，但是在运行时加载一些"通知"到需要记录日志的"切入点-pointcut"动态地加入日志记录功能。

呼～～～怎么还是文绉绉的……说个简单的例子，来配合我们的代码：一个人，他要吃饭，当然就要吃咯，我们实现了一个Person借口，告诉有eat点方法！也写了一个该接口的实现PersonImpl.java

package cn.agatezone.spring.aop;

public interface Person {
    public void eat();
}


package cn.agatezone.spring.aop;

public class PersonImpl implements Person {
    public void eat() {
        System.out.println(&#34;oh! i'm eating now!&#34;);
    }
}

这个人原本是下层阶级的典型，饭前不洗手。但是有一天他变成了中层阶级的典型，要洗手再吃饭了，怎么办？重写Person借口，加入一个方法washhands()？还是在PersonImpl的实例中重写eat方法，在原本方法段前加入洗手方法调用？着不太好吧，这个还是简单的例子，要是项目大了，Person的实现多了好多，怎么办？还是一个一个重写？不用的，aop来帮助我们，不就是饭前洗手吗？我们只要实现一个MethodBeforeAdvice借口就解决这个问题啦！看看我的代码：

package cn.agatezone.spring.aop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeEat implements MethodBeforeAdvice {
   [...]]]></description>
			<content:encoded><![CDATA[<p>其实我的个人表达能力不是很好……估计小时候语文没学好～也可能是aop这个概念本身意会的程度很大吧！呵呵寒暄一下！</p>
<p>正式进入主题：AOP 即 Aspect Oriented Programming 的缩写，中文译为"面向切面编程"。本篇没那么学术化，只是为了快速入门了解真实的使用方式！我们不用那么早去想这个名词的意义，fellow me，用真实的代码透析AOP的含义。</p>
<p>不知各位有没有项目开发的经验，如果有的话你应该可以清楚地了解到我们的代码中常常充斥着大量的日志记录代码，我们用log4j等日志记录工具一段一段地记录程序运行的信息。也许有个别是十分特殊的，但是似乎大部分都是例行公事吧！或者在丢出exception的时候捕获其message然后记入日志对吗？这样的代码难道不觉得碍眼？修改起来是不是也很麻烦？要是我们换了一个日志记录工具怎么办？呵呵，别吓到了，没这么严重啦，这些都是极端情况，平时我们还是很开心地写着这些东西。但是今天要说到的这个aop可以将一些特别的操作提取出来，作为我们的"通知-advice"，在运行时加载到对象中。就是说，我们可以在代码中不写日志记录段，但是在运行时加载一些"通知"到需要记录日志的"切入点-pointcut"动态地加入日志记录功能。<br />
<span id="more-27"></span><br />
呼～～～怎么还是文绉绉的……说个简单的例子，来配合我们的代码：一个人，他要吃饭，当然就要吃咯，我们实现了一个Person借口，告诉有eat点方法！也写了一个该接口的实现PersonImpl.java</p>
<pre class="brush: java;">
package cn.agatezone.spring.aop;

public interface Person {
    public void eat();
}
</pre>
<pre class="brush: java;">
package cn.agatezone.spring.aop;

public class PersonImpl implements Person {
    public void eat() {
        System.out.println(&quot;oh! i'm eating now!&quot;);
    }
}
</pre>
<p>这个人原本是下层阶级的典型，饭前不洗手。但是有一天他变成了中层阶级的典型，要洗手再吃饭了，怎么办？重写Person借口，加入一个方法washhands()？还是在PersonImpl的实例中重写eat方法，在原本方法段前加入洗手方法调用？着不太好吧，这个还是简单的例子，要是项目大了，Person的实现多了好多，怎么办？还是一个一个重写？不用的，aop来帮助我们，不就是饭前洗手吗？我们只要实现一个MethodBeforeAdvice借口就解决这个问题啦！看看我的代码：</p>
<pre class="brush: java;">
package cn.agatezone.spring.aop;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeEat implements MethodBeforeAdvice {
    /*
     * 这里的method就是被托管的bean(我们这里的Person)中的方法
     * 这里的args是指 对应方法(这里是指Person中的任何方法)中的参数
     */
    public void before(Method method, Object[] args, Object target)
    throws Throwable {
        if(method.getName().equals(&quot;eat&quot;)) {
            System.out.println(&quot;before eat something i must wash my hands!&quot;);
        }
    }
}
</pre>
<p>哦，如何使用呢？当然还是xml配置文件啦！详情看我的xml如下：</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
&lt;!DOCTYPE beans PUBLIC &quot;-//SPRING//DTD BEAN//EN&quot;
    &quot;http://www.springframework.org/dtd/spring-beans.dtd&quot;&gt;
&lt;beans&gt;
    &lt;bean id=&quot;beforeEat&quot; class=&quot;cn.agatezone.spring.aop.BeforeEat&quot;/&gt;
    &lt;bean id=&quot;person&quot; class=&quot;org.springframework.aop.framework.ProxyFactoryBean&quot;&gt;
        &lt;!-- 被代理对象实现的接口--&gt;
        &lt;property name=&quot;proxyInterfaces&quot;&gt;
            &lt;value&gt;cn.agatezone.spring.aop.Person&lt;/value&gt;
        &lt;/property&gt;
        &lt;!-- 拦截器(advice)的ids --&gt;
        &lt;property name=&quot;interceptorNames&quot;&gt;
            &lt;list&gt;
                &lt;!-- 指定前面声明的那个处理bean:beforeEat --&gt;
                &lt;value&gt;beforeEat&lt;/value&gt;
            &lt;/list&gt;
        &lt;/property&gt;
        &lt;!-- 被代理的目标对象--&gt;
        &lt;property name=&quot;target&quot;&gt;
            &lt;bean class=&quot;cn.agatezone.spring.aop.PersonImpl&quot;/&gt;
        &lt;/property&gt;
    &lt;/bean&gt;
&lt;/beans&gt;
</pre>
<p>现在配置好了，我们写个测试代码用用看！</p>
<pre class="brush: java;">
package cn.agatezone.spring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import junit.framework.TestCase;

public class AopTest extends TestCase {
    private static String path =
        &quot;cn/agatezone/spring/aop/applicationContext.xml&quot;;

    private ApplicationContext ctx;

    protected void setUp() throws Exception {
        ctx = new ClassPathXmlApplicationContext(path);
    }

    protected void tearDown() throws Exception {
        ctx = null;
    }

    public void testAop() {
        Person p = (Person) ctx.getBean(&quot;person&quot;);
        p.eat();
    }
}
</pre>
<p>运行吧！看看是不是出现了</p>
<blockquote><p>  before eat something i must wash my hands!<br />
oh! i'm eating now!</p></blockquote>
<p>这就是一个再简单不过的aop例子了……至少我这么觉得。好让我们回味一下，什么是切入点？说白了就是一个方法嘛！处理这个方法无非在它1.运行前2.返回值的时候3.抛出异常的时候我们来针对其做"通知"就是我们这里的BeforeEat啦，但是我们例子只用了aop中的一种通知-运行前，即实现MethodBeforeAdvice这个接口的通知。还有返回值 和 抛异常 的大家通知可以参照文档进行自我研究啦！本文只为Spring 的 aop 开个头，进一步的学习会在以后发布。</p>
<p>提供些学习资料：</p>
<p>dev2dev 网站中有一个aop的学习文章分两部分</p>
<p>第一部分：<a href="http://dev2dev.bea.com.cn/techdoc/20051216709.html" onclick="pageTracker._trackPageview('/outgoing/dev2dev.bea.com.cn/techdoc/20051216709.html?referer=');">http://dev2dev.bea.com.cn/techdoc/20051216709.html</a><br />
第二部分：<a href="http://dev2dev.bea.com.cn/techdoc/20051223712.html" onclick="pageTracker._trackPageview('/outgoing/dev2dev.bea.com.cn/techdoc/20051223712.html?referer=');">http://dev2dev.bea.com.cn/techdoc/20051223712.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.agatezone.cn/code/archives/27/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
