<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    2012年7月3日


    版權(quán)信息: 可以任意轉(zhuǎn)載, 轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原文出處, 即下面的聲明.

    原文出處:http://blog.chenlb.com/2009/06/java-classloader-architecture.html

    jvm classLoader architecture:

    1. Bootstrap ClassLoader/啟動(dòng)類加載器 
      主要負(fù)責(zé)jdk_home/lib目錄下的核心 api 或 -Xbootclasspath 選項(xiàng)指定的jar包裝入工作。
    2. Extension ClassLoader/擴(kuò)展類加載器 
      主要負(fù)責(zé)jdk_home/lib/ext目錄下的jar包或 -Djava.ext.dirs 指定目錄下的jar包裝入工作。
    3. System ClassLoader/系統(tǒng)類加載器 
      主要負(fù)責(zé)java -classpath/-Djava.class.path所指的目錄下的類與jar包裝入工作。
    4. User Custom ClassLoader/用戶自定義類加載器(java.lang.ClassLoader的子類) 
      在程序運(yùn)行期間, 通過java.lang.ClassLoader的子類動(dòng)態(tài)加載class文件, 體現(xiàn)java動(dòng)態(tài)實(shí)時(shí)類裝入特性。

    類加載器的特性:

    1. 每個(gè)ClassLoader都維護(hù)了一份自己的名稱空間, 同一個(gè)名稱空間里不能出現(xiàn)兩個(gè)同名的類。
    2. 為了實(shí)現(xiàn)java安全沙箱模型頂層的類加載器安全機(jī)制, java默認(rèn)采用了 " 雙親委派的加載鏈 " 結(jié)構(gòu)。
    classloader-architecture

    classloader-architecture

    classloader-class-diagram

    classloader-class-diagram

    類圖中, BootstrapClassLoader是一個(gè)單獨(dú)的java類, 其實(shí)在這里, 不應(yīng)該叫他是一個(gè)java類。因?yàn)椋呀?jīng)完全不用java實(shí)現(xiàn)了。它是在jvm啟動(dòng)時(shí), 就被構(gòu)造起來的, 負(fù)責(zé)java平臺(tái)核心庫。

    自定義類加載器加載一個(gè)類的步驟

    classloader-load-class

    classloader-load-class

    ClassLoader 類加載邏輯分析, 以下邏輯是除 BootstrapClassLoader 外的類加載器加載流程:

    1. // 檢查類是否已被裝載過  
    2. Class c = findLoadedClass(name);  
    3. if (c == null ) {  
    4.      // 指定類未被裝載過  
    5.      try {  
    6.          if (parent != null ) {  
    7.              // 如果父類加載器不為空, 則委派給父類加載  
    8.              c = parent.loadClass(name, false );  
    9.          } else {  
    10.              // 如果父類加載器為空, 則委派給啟動(dòng)類加載加載  
    11.              c = findBootstrapClass0(name);  
    12.          }  
    13.      } catch (ClassNotFoundException e) {  
    14.          // 啟動(dòng)類加載器或父類加載器拋出異常后, 當(dāng)前類加載器將其  
    15.          // 捕獲, 并通過findClass方法, 由自身加載  
    16.          c = findClass(name);  
    17.      }  
    18. }  

    線程上下文類加載器
    java默認(rèn)的線程上下文類加載器是 系統(tǒng)類加載器(AppClassLoader)。

    1. // Now create the class loader to use to launch the application  
    2. try {  
    3.     loader = AppClassLoader.getAppClassLoader(extcl);  
    4. catch (IOException e) {  
    5.     throw new InternalError(  
    6. "Could not create application class loader" );  
    7. }   
    8.   
    9. // Also set the context class loader for the primordial thread.  
    10. Thread.currentThread().setContextClassLoader(loader);  

    以上代碼摘自sun.misc.Launch的無參構(gòu)造函數(shù)Launch()。

    使用線程上下文類加載器, 可以在執(zhí)行線程中, 拋棄雙親委派加載鏈模式, 使用線程上下文里的類加載器加載類.
    典型的例子有, 通過線程上下文來加載第三方庫jndi實(shí)現(xiàn), 而不依賴于雙親委派.
    大部分java app服務(wù)器(jboss, tomcat..)也是采用contextClassLoader來處理web服務(wù)。
    還有一些采用 hotswap 特性的框架, 也使用了線程上下文類加載器, 比如 seasar (full stack framework in japenese).

    線程上下文從根本解決了一般應(yīng)用不能違背雙親委派模式的問題.
    使java類加載體系顯得更靈活.

    隨著多核時(shí)代的來臨, 相信多線程開發(fā)將會(huì)越來越多地進(jìn)入程序員的實(shí)際編碼過程中. 因此,
    在編寫基礎(chǔ)設(shè)施時(shí), 通過使用線程上下文來加載類, 應(yīng)該是一個(gè)很好的選擇。

    當(dāng)然, 好東西都有利弊. 使用線程上下文加載類, 也要注意, 保證多根需要通信的線程間的類加載器應(yīng)該是同一個(gè),
    防止因?yàn)椴煌念惣虞d器, 導(dǎo)致類型轉(zhuǎn)換異常(ClassCastException)。

    為什么要使用這種雙親委托模式呢?

    1. 因?yàn)檫@樣可以避免重復(fù)加載,當(dāng)父親已經(jīng)加載了該類的時(shí)候,就沒有必要子ClassLoader再加載一次。
    2. 考慮到安全因素,我們試想一下,如果不使用這種委托模式,那我們就可以隨時(shí)使用自定義的String來動(dòng)態(tài)替代java核心api中定義類型,這樣會(huì)存在非常大的安全隱患,而雙親委托的方式,就可以避免這種情況,因?yàn)镾tring已經(jīng)在啟動(dòng)時(shí)被加載,所以用戶自定義類是無法加載一個(gè)自定義的ClassLoader。

    java動(dòng)態(tài)載入class的兩種方式:

    1. implicit隱式,即利用實(shí)例化才載入的特性來動(dòng)態(tài)載入class
    2. explicit顯式方式,又分兩種方式:
      1. java.lang.Class的forName()方法
      2. java.lang.ClassLoader的loadClass()方法

    用Class.forName加載類

    Class.forName使用的是被調(diào)用者的類加載器來加載類的。
    這種特性, 證明了java類加載器中的名稱空間是唯一的, 不會(huì)相互干擾。
    即在一般情況下, 保證同一個(gè)類中所關(guān)聯(lián)的其他類都是由當(dāng)前類的類加載器所加載的。

    1. public static Class forName(String className)  
    2.      throws ClassNotFoundException {  
    3.      return forName0(className, true , ClassLoader.getCallerClassLoader());  
    4. }   
    5.   
    6. /** Called after security checks have been made. */  
    7. private static native Class forName0(String name, boolean initialize,  
    8. ClassLoader loader)  
    9.      throws ClassNotFoundException;  

    上面中 ClassLoader.getCallerClassLoader 就是得到調(diào)用當(dāng)前forName方法的類的類加載器

    static塊在什么時(shí)候執(zhí)行?

    • 當(dāng)調(diào)用forName(String)載入class時(shí)執(zhí)行,如果調(diào)用ClassLoader.loadClass并不會(huì)執(zhí)行.forName(String,false,ClassLoader)時(shí)也不會(huì)執(zhí)行.
    • 如果載入Class時(shí)沒有執(zhí)行static塊則在第一次實(shí)例化時(shí)執(zhí)行.比如new ,Class.newInstance()操作
    • static塊僅執(zhí)行一次

    各個(gè)java類由哪些classLoader加載?

    • java類可以通過實(shí)例.getClass.getClassLoader()得知
    • 接口由AppClassLoader(System ClassLoader,可以由ClassLoader.getSystemClassLoader()獲得實(shí)例)載入
    • ClassLoader類由bootstrap loader載入

    NoClassDefFoundError和ClassNotFoundException

    • NoClassDefFoundError:當(dāng)java源文件已編譯成.class文件,但是ClassLoader在運(yùn)行期間在其搜尋路徑load某個(gè)類時(shí),沒有找到.class文件則報(bào)這個(gè)錯(cuò)
    • ClassNotFoundException:試圖通過一個(gè)String變量來創(chuàng)建一個(gè)Class類時(shí)不成功則拋出這個(gè)異常
    posted @ 2013-06-20 10:25 陳睿 閱讀(362) | 評(píng)論 (1)編輯 收藏

    一:使用場景

       1)使用的地方:樹形結(jié)構(gòu),分支結(jié)構(gòu)等

       2)使用的好處:降低客戶端的使用,為了達(dá)到元件與組合件使用的一致性,增加了元件的編碼

       3)使用后的壞處:代碼不容易理解,需要你認(rèn)真去研究,發(fā)現(xiàn)元件與組合件是怎么組合的

    二:一個(gè)實(shí)際的例子

        畫圖形,這個(gè)模式,稍微要難理解一點(diǎn),有了例子就說明了一切,我畫的圖是用接口做的,代碼實(shí)現(xiàn)是抽象類為基類,你自己選擇了,接口也可以。

       


    1)先建立圖形元件

       package com.mike.pattern.structure.composite;
    /**
    * 圖形元件

    * @author taoyu

    * @since 2010-6-23
    */
    public abstract class Graph {
    /**圖形名稱*/
    protected String name;

    public Graph(String name){
       this.name=name;
    }

    /**畫圖*/
    public abstract void draw()throws GraphException;

    /**添加圖形*/
    public abstract void add(Graph graph)throws GraphException;

    /**移掉圖形*/
    public abstract void remove(Graph graph)throws GraphException;

    }

    2)建立基礎(chǔ)圖形圓

    package com.mike.pattern.structure.composite;
    import static com.mike.util.Print.print;

    /**
    * 圓圖形

    * @author taoyu

    * @since 2010-6-23
    */
    public class Circle extends Graph {

    public Circle(String name){
       super(name);
    }

    /**
    * 圓添加圖形
    * @throws GraphException 
    */
    @Override
    public void add(Graph graph) throws GraphException {
       throw new GraphException("圓是基礎(chǔ)圖形,不能添加");
    }

    /**
    * 圓畫圖
    */
    @Override
    public void draw()throws GraphException {
       print(name+"畫好了");
    }

    /**
    * 圓移掉圖形
    */
    @Override
    public void remove(Graph graph)throws GraphException {
       throw new GraphException("圓是基礎(chǔ)圖形,不能移掉");
    }

    }

    3)建立基礎(chǔ)圖形長方形

    package com.mike.pattern.structure.composite;
    import static com.mike.util.Print.print;
    /**
    * 長方形

    * @author taoyu

    * @since 2010-6-23
    */
    public class Rectangle extends Graph {

    public Rectangle(String name){
       super(name);
    }

    /**
    * 長方形添加
    */
    @Override
    public void add(Graph graph) throws GraphException {
       throw new GraphException("長方形是基礎(chǔ)圖形,不能添加");
    }

    /**
    * 畫長方形
    */
    @Override
    public void draw() throws GraphException {
       print(name+"畫好了");
    }

    @Override
    public void remove(Graph graph) throws GraphException {
       throw new GraphException("長方形是基礎(chǔ)圖形,不能移掉");
    }

    }

    4)最后簡歷組合圖形

    package com.mike.pattern.structure.composite;

    import java.util.ArrayList;
    import java.util.List;
    import static com.mike.util.Print.print;

    /**
    * 圖形組合體

    * @author taoyu

    * @since 2010-6-23
    */
    public class Picture extends Graph {
    private List<Graph> graphs;

    public Picture(String name){
       super(name);
       /**默認(rèn)是10個(gè)長度*/
       graphs=new ArrayList<Graph>();
    }


    /**
    * 添加圖形元件
    */
    @Override
    public void add(Graph graph) throws GraphException {
       graphs.add(graph);
    }

    /**
    * 圖形元件畫圖
    */
    @Override
    public void draw() throws GraphException {
       print("圖形容器:"+name+" 開始創(chuàng)建");
       for(Graph g : graphs){
        g.draw();
       }
    }

    /**
    * 圖形元件移掉圖形元件
    */
    @Override
    public void remove(Graph graph) throws GraphException {
       graphs.remove(graph);
    }

    }

    5)最后測試

    public static void main(String[] args)throws GraphException {
       /**畫一個(gè)圓,圓里包含一個(gè)圓和長方形*/
       Picture picture=new Picture("立方體圓");
       picture.add(new Circle("圓"));
       picture.add(new Rectangle("長方形"));
      
       Picture root=new Picture("怪物圖形"); 
       root.add(new Circle("圓"));
       root.add(picture);
       root.draw();
    }

    6)使用心得:的確降低了客戶端的使用情況,讓整個(gè)圖形可控了,當(dāng)是你要深入去理解,才真名明白采用該模式的含義,不太容易理解。

    posted @ 2012-08-06 17:49 陳睿 閱讀(242) | 評(píng)論 (0)編輯 收藏

    一:使用場景

         1)使用的地方:我想使用兩個(gè)不同類的方法,這個(gè)時(shí)候你需要把它們組合起來使用

         2)目前使用的情況:我會(huì)把兩個(gè)類用戶組合的方式放到一起,編程思想think in java里已經(jīng)提到個(gè),能盡量用組合就用組合,繼承一般考慮再后。

         3)使用后的好處:你不需要改動(dòng)以前的代碼,只是新封裝了一新類,由這個(gè)類來提供兩個(gè)類的方法,這個(gè)時(shí)候:一定會(huì)想到facade外觀模式,本來是多個(gè)類使用的情況,我新封裝成一個(gè)類來使用,而這個(gè)類我采用組合的方式來包裝新的方法。我的理解是,設(shè)計(jì)模式本身就是為了幫助解決特定的業(yè)務(wù)場景而故意把模式劃分對(duì)應(yīng)的模式類別,其實(shí)大多數(shù)情況,都解決了同樣的問題,這個(gè)時(shí)候其實(shí)沒有必要過多的糾纏到模式的名字上了,你有好的注意,你甚至取一個(gè)新的名字來概括這樣的使用場景。

        4)使用的壞處:適配器模式,有兩種方式來實(shí)現(xiàn)。一個(gè)是組合一個(gè)是繼承,我覺得,首先應(yīng)該考慮組合,能用組合就不要用繼承,這是第一個(gè)。第二個(gè),你采用繼承來實(shí)現(xiàn),那肯定會(huì)加大繼承樹結(jié)構(gòu),如果你的繼承關(guān)系本身就很復(fù)雜了,這肯定會(huì)加大繼承關(guān)系的維護(hù),不有利于代碼的理解,或則更加繁瑣。繼承是為了解決重用的為題而出現(xiàn)的,所以我覺得不應(yīng)該濫用繼承,有機(jī)會(huì)可以考慮同樣別的方案。

    二:一個(gè)實(shí)際的例子

          關(guān)聯(lián)營銷的例子,用戶購買完商品后,我又推薦他相關(guān)別的商品

          由于減少代碼,方法我都不采用接口,直接由類來提供,代碼只是一個(gè)范例而已,都精簡了。

    1)創(chuàng)建訂單信息

    public class Order {
    private Long orderId;
    private String nickName;

    public Order(Long orderId,String nickName){
       this.orderId=orderId;
       this.nickName=nickName;
    }

    /**
    * 用戶下訂單
    */
    public void insertOrder(){
      
    }
    }

    2)商品信息

    public class Auction {
    /**商品名稱*/
    private String name;

    /**制造商*/
    private String company;

    /**制造日期*/
    private Date date;


    public Auction(String name,String company, Date date){
       this.name=name;
       this.company=company;
       this.date=date;
    }

    /**
    * 推廣的商品列表
    */
    public void commendAuction(){
      
    }

    }

    3)購物

    public class Trade {
    /**用戶訂單*/
    private Order order;

    /**商品信息*/
    private Auction auction;

    public Trade(Order order ,Auction auction){
       this.order=order;
       this.auction=auction;
    }

    /**
    * 用戶產(chǎn)生訂單以及后續(xù)的事情
    */
    public void trade(){
       /**下訂單*/
       order.insertOrder();
      
       /**關(guān)聯(lián)推薦相關(guān)的商品*/
       auction.commendAuction();
    }

    }

       4)使用心得:其實(shí)外面采用了很多繼承的方式,order繼承auction之后,利用super .inserOrder()再加一個(gè)auction.recommendAuction(),實(shí)際上大同小異,我到覺得采用組合更容易理解以及代碼更加優(yōu)美點(diǎn)。

    posted @ 2012-08-06 17:38 陳睿 閱讀(260) | 評(píng)論 (0)編輯 收藏

    一:使用場景

       1)使用到的地方:如果你想創(chuàng)建類似汽車這樣的對(duì)象,首先要?jiǎng)?chuàng)建輪子,玻璃,桌椅,發(fā)動(dòng)機(jī),外廓等,這些部件都創(chuàng)建好后,最后創(chuàng)建汽車成品,部件的創(chuàng)建和汽車的組裝過程本身都很復(fù)雜的情況,希望把部件的創(chuàng)建和成品的組裝分開來做,這樣把要做的事情分割開來,降低對(duì)象實(shí)現(xiàn)的復(fù)雜度,也降低以后成本的維護(hù),把汽車的部件創(chuàng)建和組裝過程獨(dú)立出兩個(gè)對(duì)應(yīng)的工廠來做,有點(diǎn)類似建立兩個(gè)對(duì)應(yīng)的部件創(chuàng)建工廠和汽車組裝工廠兩個(gè)工廠,而工廠只是創(chuàng)建一個(gè)成品,并沒有把里面的步驟也獨(dú)立出來,應(yīng)該說Builder模式比工廠模式又進(jìn)了一步。

        2)采用Builder模式后的好處:把一個(gè)負(fù)責(zé)的對(duì)象的創(chuàng)建過程分解,把一個(gè)對(duì)象的創(chuàng)建分成兩個(gè)對(duì)象來負(fù)責(zé)創(chuàng)建,代碼更有利于維護(hù),可擴(kuò)性比較好。

       3)采用Builder模式后的壞處:實(shí)現(xiàn)起來,對(duì)應(yīng)的接口以及部件的對(duì)象的創(chuàng)建比較多,代碼相對(duì)來講,比較多了,估計(jì)剛開始你會(huì)有點(diǎn)暈,這個(gè)可以考慮代碼精簡的問題,增加代碼的可讀性。  

    二:一個(gè)實(shí)際的例子

    汽車的組裝

      1)首先創(chuàng)建汽車這個(gè)成品對(duì)象,包含什么的成員

    public class Car implements Serializable{

    /**
    * 汽車序列號(hào)
    */
    private static final long serialVersionUID = 1L;

    /**汽車輪子*/
    private Wheel wheel;

    /**汽車發(fā)動(dòng)機(jī)*/
    private Engine engine;

    /**汽車玻璃*/
    private Glass glass;

    /**汽車座椅*/
    private Chair chair;


    public Wheel getWheel() {
       return wheel;
    }

    public void setWheel(Wheel wheel) {
       this.wheel = wheel;
    }

    public Engine getEngine() {
       return engine;
    }

    public void setEngine(Engine engine) {
       this.engine = engine;
    }

    public Glass getGlass() {
       return glass;
    }

    public void setGlass(Glass glass) {
       this.glass = glass;
    }

    public Chair getChair() {
       return chair;
    }

    public void setChair(Chair chair) {
       this.chair = chair;
    }

    }

    2)創(chuàng)建對(duì)應(yīng)汽車零部件

    public class Wheel {
    public Wheel(){
       print("--汽車輪子構(gòu)建完畢--");
    }
    }

    public class Engine {
    public Engine(){
       print("--汽車發(fā)動(dòng)機(jī)構(gòu)建完畢--");
    }
    }

    public class Glass {
    public Glass(){
       print("--汽車玻璃構(gòu)建完畢--");
    }
    }

    public class Chair {
    public Chair(){
       print("--汽車座椅構(gòu)建完畢--");
    }
    }

    3)開始重點(diǎn)了,汽車成品的組裝過程

       public interface Builder {
    /**組裝汽車輪子*/
    public void buildWheel();

    /**組裝汽車發(fā)動(dòng)機(jī)*/
    public void buildEngine();

    /**組裝汽車玻璃*/
    public void buildGlass();

    /**組裝汽車座椅*/
    public void buildChair();

    /**返回組裝好的汽車*/
    public Car getCar();
    }

    以及實(shí)現(xiàn)類

    public class CarBuilder implements Builder {
    /**汽車成品*/
    private Car car;

    public CarBuilder(){
       car=new Car();
    }

    /**組裝汽車輪子*/
    @Override
    public void buildChair() {
       car.setChair(new Chair());
    }

    /**組裝汽車發(fā)動(dòng)機(jī)*/
    @Override
    public void buildEngine() {
       car.setEngine(new Engine());
    }

    /**組裝汽車玻璃*/
    @Override
    public void buildGlass() {
       car.setGlass(new Glass());
    }

    /**組裝汽車座椅*/
    @Override
    public void buildWheel() {
       car.setWheel(new Wheel());
    }

    /**返回組裝好的汽車*/
    @Override
    public Car getCar() {
       buildChair();
       buildEngine();
       buildGlass();
       buildWheel();
       print("--整個(gè)汽車構(gòu)建完畢--");
       return car;
    }

    }

    4)最后汽車創(chuàng)建測試

       public static void main(String[] args) {
       /**創(chuàng)建汽車組裝*/
       Builder carBuilder=new CarBuilder();
       Car car=carBuilder.getCar();
    }

       最后輸出:

    --汽車座椅構(gòu)建完畢--
    --汽車發(fā)動(dòng)機(jī)構(gòu)建完畢--
    --汽車玻璃構(gòu)建完畢--
    --汽車輪子構(gòu)建完畢--
    --整個(gè)汽車構(gòu)建完畢--

       5)體會(huì)心得:Builder模式實(shí)際的重點(diǎn)就把汽車的組裝過程和零部件的生產(chǎn)分開來實(shí)現(xiàn),零部件的生成主要靠自己的對(duì)象來實(shí)現(xiàn),我上面只是在構(gòu)造函數(shù)里創(chuàng)建了,比較簡單,而重點(diǎn)汽車的組裝則交給CarBuilder來實(shí)現(xiàn),最終由builder來先負(fù)責(zé)零部件的創(chuàng)建,最后返回出成品的汽車。

    posted @ 2012-08-06 17:37 陳睿 閱讀(258) | 評(píng)論 (0)編輯 收藏

    一:使用場景

        1)經(jīng)常使用的地方:一個(gè)類只有一個(gè)實(shí)例,eg:頁面訪問統(tǒng)計(jì)pv,統(tǒng)計(jì)的個(gè)數(shù)就只能保證一個(gè)實(shí)例的統(tǒng)計(jì)。

        2)我們目前使用的情況:比如我想創(chuàng)建一個(gè)對(duì)象,這個(gè)對(duì)象希望只有一份實(shí)例的維護(hù),在內(nèi)存的保存也只有一份,也就是在同一個(gè)jvm的java堆里只保存一份實(shí)例對(duì)象,所以你會(huì)想一辦法,在創(chuàng)建這個(gè)對(duì)象的時(shí)候,就已經(jīng)能保證只有一份。

        3)怎么改進(jìn):定義該對(duì)象的時(shí)候,就保證是同一份實(shí)例,比如:定義為私有構(gòu)造函數(shù),防止通過new的方式可以創(chuàng)建對(duì)象,然后在對(duì)象里定義一個(gè)靜態(tài)的私有成員(本身對(duì)象的一個(gè)實(shí)例),然后再創(chuàng)建一個(gè)外面訪問該對(duì)象的方法就好了。

        4)改進(jìn)的好處:代碼在編譯代碼這個(gè)級(jí)別就被控制了,不至于在jvm里運(yùn)行的時(shí)候才來保證,把唯一實(shí)例的創(chuàng)建保證在編譯階段;jvm里內(nèi)存只有一份,從而內(nèi)存占有率更低,以及更方便java垃圾回收

        5)改進(jìn)后的壞處:只能是代碼稍微需要更多點(diǎn),其實(shí)大家最后發(fā)現(xiàn)改進(jìn)后的壞處,都是代碼定義比之間要多一點(diǎn),但以后的維護(hù)代碼就降下來了,也短暫的代碼量偏大來換取以后代碼的精簡。

    二:一個(gè)實(shí)際的例子

    總體的例子

    package com.mike.pattern.singleton;

    /**
    * 總統(tǒng)

    * @author taoyu

    * @since 2010-6-22
    */
    public class President {
    private President(){
       System.out.println("總統(tǒng)已經(jīng)選舉出來了");
    }

    /**總統(tǒng)只有一個(gè)*/
    private static President president=new President();

    /**
    * 返回總統(tǒng)
    */
    public static President getPresident(){
       return president;
    }

    /**
    * 總統(tǒng)宣布選舉成功
    */
    public void announce(){
       System.out.println("偉大的中國人民,我將成你們新的總統(tǒng)");
    }
    }

    /**
    * @param args
    */
    public static void main(String[] args) {
       President president=President.getPresident();
       president.announce();
    }

    posted @ 2012-08-06 17:33 陳睿 閱讀(469) | 評(píng)論 (0)編輯 收藏

    1.使用場景

         1)子類過多,不容易管理;構(gòu)造對(duì)象過程過長;精簡代碼創(chuàng)建;

        2)目前我們代碼情況: 編寫代碼的時(shí)候,我們經(jīng)常都在new對(duì)象,創(chuàng)建一個(gè)個(gè)的對(duì)象,而且還有很多麻煩的創(chuàng)建方式,eg:HashMap<String,Float> grade=new HashMap<String,Float>(),這樣的代碼創(chuàng)建方式太冗長了,難道你沒有想過把這個(gè)創(chuàng)建變的短一點(diǎn)么,比如:HashMap<String,Float>grade=HashMapFactory.new(),可以把你創(chuàng)建精簡一點(diǎn);你也可以還有別的需求,在創(chuàng)建對(duì)象的時(shí)候,你需要不同的情況,創(chuàng)建統(tǒng)一種類別的對(duì)象,eg:我想生成不同的汽車,創(chuàng)建小轎車,創(chuàng)建卡車,創(chuàng)建公交汽車等等,都屬于同種類別:汽車,你難道沒有想過,我把這些創(chuàng)建的對(duì)象在一個(gè)工廠里來負(fù)責(zé)創(chuàng)建,我把創(chuàng)建分開化,交給一人來負(fù)責(zé),這樣可以讓代碼更加容易管理,創(chuàng)建方式也可以簡單點(diǎn)。

    比如:Car    BMW=CarFactory.create(bmw);   把創(chuàng)建new由一個(gè)統(tǒng)一負(fù)責(zé),這樣管理起來相當(dāng)方便

        3)怎么改進(jìn):這個(gè)時(shí)候,你會(huì)想到,創(chuàng)建這樣同類別的東西,我把這個(gè)權(quán)利分出去,讓一個(gè)人來單獨(dú)管理,它只負(fù)責(zé)創(chuàng)建我的對(duì)象這個(gè)事情,所以你單獨(dú)簡歷一個(gè)對(duì)象來創(chuàng)建同類的對(duì)象,這個(gè)時(shí)候,你想這個(gè)東西有點(diǎn)像工廠一樣,生成同樣的產(chǎn)品,所以取了個(gè)名字:工廠模式,顧名思義,只負(fù)責(zé)對(duì)象的創(chuàng)建

        4)改進(jìn)后的好處:代碼更加容易管理了,代碼的創(chuàng)建要簡潔很多。

        5)改進(jìn)后的壞處:那就是你需要單獨(dú)加一個(gè)工廠對(duì)象來負(fù)責(zé)創(chuàng)建,多需要寫點(diǎn)代碼。

    2.一個(gè)實(shí)際的例子

       創(chuàng)建寶馬汽車與奔馳汽車的例子

       1)先提取出一個(gè)汽車的公用接口Car

           public interface Car{

              /**行駛*/    

              public void drive();

            }

       2)寶馬和奔馳汽車對(duì)象

    public class BMWCar implements Car {

    /**
    * 汽車發(fā)動(dòng)
    */
    public void drive(){
       System.out.println("BMW Car drive");
    }
    }

    public class BengCar implements Car {

    /**
    * 汽車發(fā)動(dòng)
    */
    public void drive(){
       System.out.println("BengChi Care drive");
    }
    }

        3)單獨(dú)一個(gè)汽車工廠來負(fù)責(zé)創(chuàng)建

         public class FactoryCar {
    /**
    * 制造汽車
    *
    * @param company 汽車公司
    * @return 汽車
    * @throws CreateCarException 制造汽車失敗異常
    */
    public static Car createCar(Company company)throws CreateCarException{
       if(company==Company.BMW){
        return new BMWCar();
       }else if(company==Company.Beng){
        return new BengCar();
       }
       return null;
    }
    }

        4)最后的代碼實(shí)現(xiàn):

        Car BMWCar=FactoryCar.createCar(Company.BMW);
         BMWCar.drive();

    posted @ 2012-08-06 17:28 陳睿 閱讀(263) | 評(píng)論 (0)編輯 收藏

       1. 我說下我對(duì)設(shè)計(jì)模式的理解:任何一樣事物都是因?yàn)橛行枨蟮尿?qū)動(dòng)才誕生的,所以設(shè)計(jì)模式也不例外,我們平時(shí)在編寫代碼的時(shí)候,隨著時(shí)間的深入,發(fā)現(xiàn)很多代碼很難維護(hù),可擴(kuò)展性級(jí)差,以及代碼的效率也比較低,這個(gè)時(shí)候你肯定會(huì)想辦法讓代碼變的優(yōu)美又能解決你項(xiàng)目中的問題,所以在面向?qū)ο笳Z言里,你肯定會(huì)去發(fā)現(xiàn)很多可以重用的公用的方法,比如:接口的存在,你自然就想到了,讓你定義的方法與你的實(shí)現(xiàn)分開,也可以很方便把不同的類與接口匹配起來,形成了一個(gè)公用的接口,你會(huì)發(fā)現(xiàn)這樣做,好處會(huì)是非常多的,解決了你平時(shí)想把代碼的申明與邏輯實(shí)現(xiàn)的分開。

        2. 這個(gè)時(shí)候,你發(fā)現(xiàn)了,本身面向?qū)ο蟮恼Z言里,已經(jīng)暗藏了很多好處,你肯定會(huì)仔細(xì)去分析面向?qū)ο筮@個(gè)語言,認(rèn)真去挖掘里面更多的奧秘,最后,你發(fā)現(xiàn)了,原來你可以把面向?qū)ο蟮奶匦蕴崛〕梢粋€(gè)公用的實(shí)現(xiàn)案例,這些案例里能幫助你解決你平時(shí)編寫代碼的困擾,而這樣一群人,就是所謂gof的成員,他們從平時(shí)設(shè)計(jì)建筑方面找到了靈感,建筑的設(shè)計(jì)也可以公用化以及重用化,所以他們也提取了相關(guān)的軟件設(shè)計(jì)方面的公用案例,也就有了下面的相關(guān)的所謂23種設(shè)計(jì)模式,而里面這么多模式,你也可以把他們歸類起來,最后發(fā)現(xiàn)就幾類模式:創(chuàng)建,結(jié)構(gòu),行為等模式類別,而這些現(xiàn)成的方案,也可以在實(shí)際應(yīng)用中充分發(fā)揮作用,隨著大家的使用以及理解,發(fā)現(xiàn)其實(shí)這些所謂的模式里,你的確可以讓你的代碼變的更加優(yōu)美與簡練。

        3. 我比較喜歡把代碼變的更加優(yōu)美與簡練,優(yōu)美的代碼就是一看就懂,結(jié)構(gòu)很清晰,而簡歷就是一目了然,又可以解決你的問題,就是代碼又少效率又高,所以平時(shí)要養(yǎng)成寫java doc的習(xí)慣,這樣的代碼才為清晰,所以才會(huì)更加優(yōu)美。

        4. 這些就是我對(duì)設(shè)計(jì)模式的理解,所以這么好的寶貝,我們不去深入的了解,的確可惜了,這就叫站到巨人的肩膀上.....

    posted @ 2012-08-06 17:22 陳睿 閱讀(218) | 評(píng)論 (0)編輯 收藏
    一:網(wǎng)絡(luò)配置

          1.關(guān)掉防火墻    
    1) 重啟后生效 
    開啟: chkconfig iptables on 
    關(guān)閉: chkconfig iptables off 
    2) 即時(shí)生效,重啟后失效 
    開啟: service iptables start 
    關(guān)閉: service iptables stop
        2.下載軟件
    wget curl
        3.安裝和解壓
            安裝 rpm -ivh
            升級(jí) rpm -Uvh
            卸載 rpm -e
            tar -zxvf 
      
    二:網(wǎng)卡設(shè)置
       1、 設(shè)置ip地址(即時(shí)生效,重啟失效)
      #ifconfig eth0 ip地址 netmask 子網(wǎng)掩碼
      
      2、 設(shè)置ip地址(重啟生效,永久生效)
      #setup
      
      3、 通過配置文件設(shè)置ip地址(重啟生效,永久生效)
      #vi /etc/sysconfig/network-scripts/ifcfg-eth0
      DEVICE=eth0 #設(shè)備名,與文件同名。
      ONBOOT=yes #在系統(tǒng)啟動(dòng)時(shí),啟動(dòng)本設(shè)備。
      BOOTPROTO=static
      IPADDR=202.118.75.91 #此網(wǎng)卡的IP地址
      NETMASK=255.255.255.0 #子網(wǎng)掩碼
      GATEWAY=202.118.75.1 #網(wǎng)關(guān)IP
      MACADDR=00:02:2D:2E:8C:A8 #mac地址
      
      4、 重啟網(wǎng)絡(luò)服務(wù)
      #service network restart //重啟所有網(wǎng)卡
      
      5、 禁用網(wǎng)卡,啟動(dòng)網(wǎng)卡
      #ifdown eth0
      #ifup eth0
      
      6、 屏蔽網(wǎng)卡,顯示網(wǎng)卡
      #ifconfig eth0 down
      #ifconfig eth0 up
      
      7、 配置DNS客戶端(最多三個(gè))
      #vi /etc/resolv.conf
      nameserver 202.99.96.68
      
      8、更改主機(jī)名(即時(shí)生效)
      #hostname 主機(jī)名
      
      9、更改主機(jī)名(重啟計(jì)算機(jī)生效,永久生效)
      #vi /etc/sysconfig/network
      HOSTNAME=主機(jī)名
    三:兩臺(tái)linux拷貝命令:scp

    1.安裝scp:yum install openssh-clients 
    2.scp  -r 本地用戶名@IP地址:文件名1 遠(yuǎn)程用戶名@IP地址:文件名2
    posted @ 2012-07-24 10:28 陳睿 閱讀(203) | 評(píng)論 (0)編輯 收藏
         摘要: 作者:NetSeek http://www.linuxtone.org (IT運(yùn)維專家網(wǎng)|集群架構(gòu)|性能調(diào)優(yōu))歡迎轉(zhuǎn)載,轉(zhuǎn)載時(shí)請(qǐng)務(wù)必以超鏈接形式標(biāo)明文章原始出處和作者信息及本聲明.首發(fā)時(shí)間: 2008-11-25 更新時(shí)間:2009-1-14目 錄一、 Nginx 基礎(chǔ)知識(shí)二、 Nginx 安裝及調(diào)試三、 Nginx Rewrite四、 Nginx Redirect五、 Nginx 目錄自動(dòng)加斜線...  閱讀全文
    posted @ 2012-07-06 11:09 陳睿 閱讀(459) | 評(píng)論 (0)編輯 收藏
    一:quartz簡介
           OpenSymphony 的Quartz提供了一個(gè)比較完美的任務(wù)調(diào)度解決方案。
           Quartz 是個(gè)開源的作業(yè)調(diào)度框架,定時(shí)調(diào)度器,為在 Java 應(yīng)用程序中進(jìn)行作業(yè)調(diào)度提供了簡單卻強(qiáng)大的機(jī)制。
           Quartz中有兩個(gè)基本概念:作業(yè)和觸發(fā)器。作業(yè)是能夠調(diào)度的可執(zhí)行任務(wù),觸發(fā)器提供了對(duì)作業(yè)的調(diào)度

    二:quartz spring配置詳解
    •  為什么不適用java.util.Timer結(jié)合java.util.TimerTask 
            1.主要的原因,適用不方便,特別是制定具體的年月日時(shí)分的時(shí)間,而quartz使用類似linux上的cron配置,很方便的配置每隔時(shí)間執(zhí)行觸發(fā)。

            2.其次性能的原因,使用jdk自帶的Timer不具備多線程,而quartz采用線程池,性能上比timer高出很多。


    •    詳解quartz在spring里面的配置
        在spring里主要分為兩種使用方式:第一種,也是目前使用最多的方式,spring提供的MethodInvokingJobDetailFactoryBean代理類,通過雷利類直接調(diào)用任務(wù)類的某個(gè)函數(shù);第二種,程序里實(shí)現(xiàn)quartz接口,quartz通過該接口進(jìn)行調(diào)度。

          主要講解通過spring提供的代理類MethodInvokingJobDetailFactoryBean

            1.業(yè)務(wù)邏輯類:業(yè)務(wù)邏輯是獨(dú)立的,本身就與quartz解耦的,并沒有深入進(jìn)去,這對(duì)業(yè)務(wù)來講是很好的一個(gè)方式。

                            public class  TestJobTask{
         

          /**
           *業(yè)務(wù)邏輯處理
           
    */
            public void   service(){
                /**業(yè)務(wù)邏輯*/
                    ..
            }

    }
           
        2.增加一個(gè)線程池
        <!-- 線程執(zhí)行器配置,用于任務(wù)注冊 -->
    <bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
     <property name="corePoolSize" value="10" />
     <property name="maxPoolSize" value="100" />
     <property name="queueCapacity" value="500" />
    </bean>

      3.定義業(yè)務(wù)邏輯類

        <!-- 業(yè)務(wù)對(duì)象 -->
    <bean id="testJobTask" class="com.mike.scheduling.TestJobTask" />


        4.增加quartz調(diào)用業(yè)務(wù)邏輯

        <!-- 調(diào)度業(yè)務(wù) -->
    <bean id="jobDetail" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
     <property name="targetObject" ref="testJobTask" />
     <property name="targetMethod" value="service" />
    </bean>

        5.增加調(diào)用的觸發(fā)器,觸發(fā)的時(shí)間,有兩種方式:

         第一種觸發(fā)時(shí)間,采用類似linux的cron,配置時(shí)間的表示發(fā)出豐富  
      <bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean">
     <property name="jobDetail" ref="jobDetail" />
     <property name="cronExpression" value="10 0/1 * * * ?" />
    </bean>
      Cron表達(dá)式“10 */1 * * * ?”意為:從10秒開始,每1分鐘執(zhí)行一次 
      
        第二種,采用比較簡話的方式,申明延遲時(shí)間和間隔時(shí)間
      <bean id="taskTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean">
     <property name="jobDetail" ref="jobDetail" />
     <property name="startDelay" value="10000" />
     <property name="repeatInterval" value="60000" />
    </bean>
      延遲10秒啟動(dòng),然后每隔1分鐘執(zhí)行一次 

        6.開始調(diào)用

          <!-- 設(shè)置調(diào)度 -->
    <bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
     <property name="triggers">
      <list>
       <ref bean="cronTrigger" />
      </list>
     </property>
     <property name="taskExecutor" ref="executor" />
    </bean>

       7.結(jié)束:啟動(dòng)容器即可,已經(jīng)將spring和quartz結(jié)合完畢。

        Cron常用的表達(dá)式
        "0 0 12 * * ?" 每天中午12點(diǎn)觸發(fā)
    "0 15 10 ? * *" 每天上午10:15觸發(fā)
    "0 15 10 * * ?" 每天上午10:15觸發(fā)
    "0 15 10 * * ? *" 每天上午10:15觸發(fā)
    "0 15 10 * * ? 2005" 2005年的每天上午10:15觸發(fā)
    "0 * 14 * * ?" 在每天下午2點(diǎn)到下午2:59期間的每1分鐘觸發(fā)
    "0 0/5 14 * * ?" 在每天下午2點(diǎn)到下午2:55期間的每5分鐘觸發(fā)
    "0 0/5 14,18 * * ?" 在每天下午2點(diǎn)到2:55期間和下午6點(diǎn)到6:55期間的每5分鐘觸發(fā)
    "0 0-5 14 * * ?" 在每天下午2點(diǎn)到下午2:05期間的每1分鐘觸發(fā)
    "0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44觸發(fā)
    "0 15 10 ? * MON-FRI" 周一至周五的上午10:15觸發(fā)
    "0 15 10 15 * ?" 每月15日上午10:15觸發(fā)
    "0 15 10 L * ?" 每月最后一日的上午10:15觸發(fā)
    "0 15 10 ? * 6L" 每月的最后一個(gè)星期五上午10:15觸發(fā) 
    "0 15 10 ? * 6L 2002-2005" 2002年至2005年的每月的最后一個(gè)星期五上午10:15觸發(fā)
    "0 15 10 ? * 6#3" 每月的第三個(gè)星期五上午10:15觸發(fā)

    三:quartz原理

        根據(jù)上面spring的配置,我們就比較清楚quartz的內(nèi)部情況,下面我們主要詳解配置涉及到的每個(gè)點(diǎn)
        1.我們先從最后一個(gè)步驟看起,SchedulerFactoryBean ,scheduler的工廠實(shí)現(xiàn),里面可以生產(chǎn)出對(duì)應(yīng)的多個(gè)jobDetail和trigger,每個(gè)jobDetail對(duì)應(yīng)trigger代表一個(gè)任務(wù)
             Quartz的SchedulerFactory是標(biāo)準(zhǔn)的工廠類,不太適合在Spring環(huán)境下使用。此外,為了保證Scheduler能夠感知 Spring容器的生命周期,完成自動(dòng)啟動(dòng)和關(guān)閉的操作,必須讓Scheduler和Spring容器的生命周期相關(guān)聯(lián)。以便在Spring容器啟動(dòng)后, Scheduler自動(dòng)開始工作,而在Spring容器關(guān)閉前,自動(dòng)關(guān)閉Scheduler。為此,Spring提供 SchedulerFactoryBean,這個(gè)FactoryBean大致?lián)碛幸韵碌墓δ埽?nbsp;
         1)以更具Bean風(fēng)格的方式為Scheduler提供配置信息; 
         2)讓Scheduler和Spring容器的生命周期建立關(guān)聯(lián),相生相息; 
         3)通過屬性配置部分或全部代替Quartz自身的配置文件。 
      2.jobDetail,表示一個(gè)可執(zhí)行的業(yè)務(wù)調(diào)用
      
      3.trigger:調(diào)度的時(shí)間計(jì)劃,什么時(shí)候,每隔多少時(shí)間可執(zhí)行等時(shí)間計(jì)劃

      4.ThreadPoolTaskExecutor,線程池,用來并行執(zhí)行每個(gè)對(duì)應(yīng)的job,提高效率,這也是上面提到不推薦使用jdk自身timer的一個(gè)很重要的原因
    posted @ 2012-07-03 14:42 陳睿 閱讀(3087) | 評(píng)論 (2)編輯 收藏

    導(dǎo)航

    <2012年7月>
    24252627282930
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    統(tǒng)計(jì)

    常用鏈接

    留言簿

    隨筆分類

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 在线日韩日本国产亚洲| 国产大片91精品免费观看不卡| 黄色三级三级三级免费看| 嫩草成人永久免费观看| 国产精品无码免费专区午夜| 91亚洲va在线天线va天堂va国产| 亚洲乱码国产一区三区| 日韩高清免费在线观看| 99re在线视频免费观看| 久久国产乱子免费精品| 色欲A∨无码蜜臀AV免费播| 免费视频精品一区二区三区 | 久久夜色精品国产亚洲| 亚洲午夜久久久久久久久久| 国内大片在线免费看| 美女被免费视频网站a国产| 18禁免费无码无遮挡不卡网站 | 免费无码AV一区二区| 精品熟女少妇aⅴ免费久久 | 久久久久亚洲AV无码专区桃色| 在线看片免费不卡人成视频| 最新中文字幕免费视频| 免费观看激色视频网站bd| 成年丰满熟妇午夜免费视频| 日本一道高清不卡免费| 亚洲乱码中文字幕手机在线| 国产在线19禁免费观看| 亚洲欧洲久久av| 亚洲bt加勒比一区二区| 亚洲欧洲日产国码无码久久99| 亚洲AV无码乱码国产麻豆穿越| 中文字幕亚洲一区| 亚洲无删减国产精品一区| 亚洲不卡在线观看| 久久精品国产亚洲AV电影网| 一级黄色毛片免费看| 日韩在线视频线视频免费网站| a级毛片免费播放| 日本精品人妻无码免费大全 | 日韩在线观看免费完整版视频| 嫩草成人永久免费观看|