javadoc的生成和java應用程序的打包和部署

javadoc命令

如果要將一個類生成文檔,該類必須是public訪問權限。例如我們要將以下的類生成javadoc文檔可以使用下面的命令:
/**
 * 這是一個可以對數組進行操作的工具類,該類中提供了,獲取最值,排序等功能。
 * 
 * @author 張三
 * @version V1.1
 */

public class ArrayTool {
	/**
	 * 無參構造
	 */
	public ArrayTool() {
	}

	/**
	 * 獲取一個整形數組中的最大值。 
	 * @param arr 接收一個int類型的數組。
	 * @return 會返回一個該數組中最大值。
	 */
	public static int getMax(int[] arr) {
		int max = 0;
		for (int x = 1; x < arr.length; x++) {
			if (arr[x] > arr[max])
				max = x;
		}
		return arr[max];
	}

	/**
	 * 給int數組進行選擇排序。
	 * @param arr 接收一個int類型的數組。
	 */
	public static void selectSort(int[] arr) {
		for (int x = 0; x < arr.length - 1; x++) {
			for (int y = x + 1; y < arr.length; y++) {
				if (arr[x] > arr[y]) {
					swap(arr, x, y);
				}
			}
		}
	}

	/**
	 * 給int數組進行冒泡排序。
	 * @param arr 接收一個int類型的數組。
	 */
	public static void bubbleSort(int[] arr) {
		for (int x = 0; x < arr.length - 1; x++) {
			for (int y = 0; y < arr.length - x - 1; y++) {
				if (arr[y] > arr[y + 1]) {
					swap(arr, y, y + 1);
				}
			}
		}
	}

	/**
	 * 給數組中元素進行位置的置換。
	 * @param arr 接收一個int類型的數組。
	 * @param a 要置換的位置
	 * @param b 要置換的位置
	 */
	private static void swap(int[] arr, int a, int b) {
		int temp = arr[a];
		arr[a] = arr[b];
		arr[b] = temp;
	}

	/**
	 * 用於打印數組中的元素。打印形式是:[elemet1, element2, ...]
	 * @param arr 接收一個int類型的數組。
	 */
	public static void printArray(int[] arr) {
		System.out.print("[");
		for (int x = 0; x < arr.length; x++) {
			if (x != arr.length - 1)
				System.out.print(arr[x] + ", ");
			else
				System.out.println(arr[x] + "]");
		}
	}
}

將類文件存放到指定目錄:

javac -d 需要存放的目錄*.java

把程序包進jar

jar就是Java ARchive。這種文件是pkzip格式的文件,它能夠讓你把一組類文件包裝起來,所以交付的時候只需要一個JAR文件。可執行的JAR代表用戶不需要把文件抽出來就能夠運行。程序可以在類文件保存在JAR的情況下執行。祕訣在於創建manifest文件,它會帶有jar的信息,告訴JVM哪個類含有main()方法!

①指定所有的類文件都在classFile目錄下;

②創建manifest.txt文件用來描述哪個類含有main()方法,該文件的格式如下:


③使用jar工具來創建帶有所有類以及manifest的JAR文件

大部分完全在本機的java應用程序都是以可執行的jar來部署的。

JVM能夠從JAR中載入類,並調用該類的main()方法。事實上整個應用程序都可以包在JAR中。一旦main()方法開始執行,JVM就不會在乎類從哪裏來,只要能夠找到就行。其中一個來源就是classpath指定位置的所有jar文件。如果看到某個JAR,則JVM就會在需要類的時候查詢此JAR。

RMI(Remote Method Invocation)

一般來說方法的調用都是發生在相同的堆上的兩個對象之間的,也就是說調用方和被調用方都在同一個堆上。

但是,如果要調用不同機器上的對象的方法怎麼辦?

遠程過程調用需要4種東西:服務器、客戶端、服務器輔助設施和客戶端輔助設施。


輔助設施的任務:

輔助設施是實際上執行通信的對象。他們會讓客戶端感覺上就好像是在調用本機的對象。客戶端是真正服務的代理(proxy)。也就是說:客戶端以爲它調用的是遠程的服務,因爲輔助設置假裝成服務對象。
但是客戶端輔助設施並不是真正的遠程服務,雖然輔助設施的舉止跟它很像(因爲它提供的方法和服務和所聲明的一樣),卻沒有任何真正客戶端需要的方法的方法和邏輯。相反,輔助設施會去連接服務器,將調用的信息傳遞過去(像是方法名稱或者參數內容),然後等待server響應。
在Server端,服務器的輔助設施會通過Socket連接來自Client設施的要求,解析打包送來的信息,然後調用真正的服務。因此對服務對象來說調用來自本地。
服務的輔助設施取得返回值之後就把它包裝後送出去(通過Socket的輸出串流)給客戶端的輔助設施。客戶端的輔助設施會解開這些信息傳送給客戶端的對象。

客戶端對象看起來像是在調用遠程的方法。但是實際上它只是在調用本地處理Socket的串流細節的“代理”。

java RMI提供客戶端和服務器端的輔助設施對象。

在RMI中,客戶端的輔助設施稱爲stub,而服務端的輔助設施稱爲skeleton。

創建遠程服務的5個步驟:

一、創建Remote接口:遠程的接口定義了客戶端可以遠程調用的方法。它是個作爲服務的多態化類。stub的服務都會實現此接口。
二、實現Remote接口:這是真正執行的類。它實現出定義在該接口上的方法。它是客戶端會調用的對象。
三、用RMIC產生stub和skeleton:客戶端和服務器都有helper。你無需創建這些類或者產生這些類的源代碼。這都會在你執行JDK所附的rmic工具時自動地處理掉。
四、啓動RMI registry:RMI registry就像是電話薄。用戶會從此處取得代理(客戶端的stub/helper對象)。
五、啓動遠程服務:你必須讓服務對象開始執行。實現服務的類會起始服務的實例並向RMI registry註冊。要有註冊後才能夠對用戶提供服務。
以下是一個簡單的範例:
一、創建遠程接口
import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * Remote是一個標記接口
 */
public interface MyRemote extends Remote {
    /*
     * 遠程接口定義了客戶端可以遠程調用的方法,是一個作爲服務的多態化類。也就是說:
     * 客戶端會調用有實現此接口的stub,而此stub因爲會執行網絡的輸入輸出工作,
     * 所以可能產生各種問題,客戶端必須處理或者聲明異常(每一個遠程調用都會被認爲是有風險的,這樣聲明會強迫客戶端注意到這件事)。
     * 
     * 遠程方法的參數和返回值都應該是primitive主數據類型或Serializable, 因爲參數和返回值都會被打包通過網絡傳送,而這依靠序列化
     */
    public String sayHello() throws RemoteException;
}
二、實現遠程接口
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * 爲了要稱爲遠程服務對象,你的對象必須要有與遠程有關的功能。其中最簡單的方式就是繼承UnicastRemoteObject
 *
 */
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
    /* UnicastRemoteObject的構造方法會拋出RemoteException。處理它的唯一方式是對它的聲明實現一個構造方法 */
    protected MyRemoteImpl() throws RemoteException {
	super();
    }

    @Override
    public String sayHello() throws RemoteException {
	return "Server says:“Hey!”";
    }

    public static void main(String[] args) {
	try {
	    MyRemote service = new MyRemoteImpl();
	    /* 向RMI registry註冊服務 */
	    Naming.rebind("RemoteHello", service);
	} catch (RemoteException e) {
	    e.printStackTrace();
	} catch (MalformedURLException e) {
	    e.printStackTrace();
	}
    }

}
三、產生stub和skeleton
四、執行rmiregistry
五、啓動服務(從另一個命令行)

客戶端如何取得stub對象?

客戶端必須取得stub對象,因爲客戶端必須要調用它的方法。這就得靠RMI registry了。客戶端會像查電話簿一樣進行搜索,找出上面有相符合的名稱的服務。
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

public class MyRemoteClient {
    public static void main(String[] args) {
	new MyRemoteClient().go();
    }

    private void go() {
	MyRemote service;
	try {
	    service = (MyRemote) Naming.lookup("rmi://127.0.0.1/RemoteHello");
	    String s = service.sayHello();	//就像是調用本機的方法,但是是有風險的
	    System.out.println(s);
	} catch (MalformedURLException e) {
	    e.printStackTrace();
	} catch (RemoteException e) {
	    e.printStackTrace();
	} catch (NotBoundException e) {
	    e.printStackTrace();
	}

    }
}
下面是遠程調用的綜合實例:
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface ServiceServer extends Remote {
    Object[]getServiceList()throws RemoteException;
    Service getService(Object serviceKey)throws RemoteException;
}
import java.io.Serializable;

import javax.swing.JPanel;

public interface Service extends Serializable{
    public JPanel getGuiPanel();
}
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.HashMap;

public class ServiceServerImpl extends UnicastRemoteObject implements ServiceServer {
    HashMap serviceList;	//服務會存儲在HashMap中
    protected ServiceServerImpl() throws RemoteException {
	setUpServices();
    }

    private void setUpServices() {
	serviceList = new HashMap();
	serviceList.put("Dice Rolling Service", new DiceService());
	serviceList.put("Day of Week Service", new DayOfWeekService());
    }

    @Override
    public Object[] getServiceList() throws RemoteException {
	System.out.println("in remote");
	return serviceList.keySet().toArray();
    }

    @Override
    public Service getService(Object serviceKey) throws RemoteException {
	Service thesService = (Service) serviceList.get(serviceKey);
	return thesService;
    }

    public static void main(String[] args) {
	try {
	    Naming.rebind("ServiceServer", new ServiceServerImpl());
	} catch (RemoteException e) {
	    e.printStackTrace();
	} catch (MalformedURLException e) {
	    e.printStackTrace();
	}
	System.out.println("Remote service is running");
    }
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class DiceService implements Service {
    JLabel label;
    JComboBox numOfDice;
    @Override
    public JPanel getGuiPanel() {
	JPanel panel = new JPanel();
	JButton button = new JButton("Roll `em!");
	String[]choices = {"1","2","3","4","5"};
	numOfDice = new JComboBox(choices);
	label = new JLabel("Dice values here");
	button.addActionListener(new ActionListener() {
	    
	    @Override
	    public void actionPerformed(ActionEvent paramActionEvent) {
		String diceOutput = "";
		String selection = (String) numOfDice.getSelectedItem();
		int numOfDiceToRoll = Integer.parseInt(selection);
		for (int i = 0; i < numOfDiceToRoll; i++) {
		    int r = (int) (Math.random()*99+1);
		    diceOutput += (" "+r);
		}
		label.setText(diceOutput);
	    }
	});
	panel.add(numOfDice);
	panel.add(button);
	panel.add(label);
	return panel;
    }

}
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class DayOfWeekService implements Service {
    JLabel outputLabel;
    JComboBox month;
    JTextField day;
    JTextField year;

    @Override
    public JPanel getGuiPanel() {
	JPanel panel = new JPanel();
	JButton button = new JButton("Do it");
	button.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent paramActionEvent) {
		int monthNum = month.getSelectedIndex();
		int dayNum = Integer.parseInt(day.getText());
		int yearNum = Integer.parseInt(year.getText());
		Calendar c = Calendar.getInstance();
		c.set(Calendar.MONTH, monthNum);
		c.set(Calendar.DAY_OF_MONTH, dayNum);
		c.set(Calendar.YEAR, yearNum);
		Date date = c.getTime();
		String dayOfWeek = new SimpleDateFormat("EEEE").format(date);
		outputLabel.setText(dayOfWeek);
	    }
	});
	outputLabel = new JLabel("Date appears here");
	DateFormatSymbols dateStuff = new DateFormatSymbols();
	month = new JComboBox(dateStuff.getMonths());
	day = new JTextField(8);
	year = new JTextField(8);
	JPanel inputPanel = new JPanel(new GridLayout(3, 2));
	inputPanel.add(new JLabel("月"));
	inputPanel.add(month);
	inputPanel.add(new JLabel("日"));
	inputPanel.add(day);
	inputPanel.add(new JLabel("年"));
	inputPanel.add(year);
	panel.add(inputPanel);
	panel.add(button);
	panel.add(outputLabel);
	return panel;
    }
}
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ServiceBrowser {
    JPanel mainPanel;
    JComboBox serviceList;
    ServiceServer server;

    public void buildGUI() {
	JFrame frame = new JFrame("RMI Browser");
	mainPanel = new JPanel();
	frame.getContentPane().add(BorderLayout.CENTER, mainPanel);

	Object[] services = getServicesList();
	serviceList = new JComboBox(services);

	frame.getContentPane().add(BorderLayout.NORTH, serviceList);
	serviceList.addActionListener(new ActionListener() {

	    @Override
	    public void actionPerformed(ActionEvent paramActionEvent) {
		Object selection = serviceList.getSelectedItem();
		loadService(selection);
	    }
	});
	frame.setSize(500, 100);
	frame.setVisible(true);
	frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private Object[] getServicesList() {
	Object obj = null;
	Object[] services = null;

	try {
	    obj = Naming.lookup("rmi://127.0.0.1/ServiceServer");
	    server = (ServiceServer) obj;
	    services = server.getServiceList();
	} catch (MalformedURLException e) {
	    e.printStackTrace();
	} catch (RemoteException e) {
	    e.printStackTrace();
	} catch (NotBoundException e) {
	    e.printStackTrace();
	}
	return services;
    }

    private void loadService(Object serviceSelection) {
	try {
	    Service svc = server.getService(serviceSelection);
	    mainPanel.removeAll();
	    mainPanel.add(svc.getGuiPanel());
	    mainPanel.validate();
	    mainPanel.repaint();
	} catch (RemoteException e) {
	    e.printStackTrace();
	}
    }

    public static void main(String[] args) {
	new ServiceBrowser().buildGUI();
    }

}
運行結果:



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章