日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK动态代理模式这篇就够了

發(fā)布時間:2024/3/7 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK动态代理模式这篇就够了 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

JDK動態(tài)代理

第一章 代理的介紹

介紹:我們需要掌握的程度

動態(tài)代理(理解) 基于反射機制

掌握的程度:

1.什么是動態(tài)代理?

2.動態(tài)代理能夠做什么?

1.1 什么是代理

  • 代理,在我們?nèi)粘I钪芯陀畜w現(xiàn),代購,中介,換ip,商家等等.

  • 比如有一家美國的大學(xué),可以對全世界招生.留學(xué)中介(代理 )

  • 留學(xué)中介(代理):幫助這家美國的學(xué)校招生,中介是學(xué)校的代理中介是代替學(xué)校完成招生功能

  • 代理特點

  • 中介和代理他們要做的事情是一致的:招生
  • 中介是學(xué)校代理,學(xué)校是目標(biāo)
  • 家長-------->中介(學(xué)校介紹,辦理入學(xué)手續(xù))---------->美國學(xué)校
  • 中介是代理,不能白干活,需要收取費用
  • 代理不讓你訪問到目標(biāo)

1.2 為什么要找中介

為什么要找中介?
1.中介是專業(yè)的,方便.
2.家長現(xiàn)在不能自己去找學(xué)校。家長沒有能力訪問學(xué)校.或者美國學(xué)校不接收個人來訪

買東西都是商家賣, 商家是某個商品的代理, 你個人買東西,肯定不會讓你接觸到廠家的.

1.3 代理在開發(fā)中的應(yīng)用

1.你有a類,本來是調(diào)用c類的方法,完成某個功能。但是c不讓a調(diào)用。

? a——不能調(diào)用c的方法

? 在a和c直接創(chuàng)建一個b代理,c讓b訪問

? a——訪問b——訪問c

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-d5t7z5Hp-1648124617810)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324103732980.png)]

2.實際例子:登錄,注冊有驗證碼,驗證碼是手機短信

? 中國移動、聯(lián)通能發(fā)短信

? 中國移動聯(lián)通有子公司或者關(guān)聯(lián)公司,他們面向社會提供短信的發(fā)送功能

3.張三項目發(fā)送短信——子公司或者關(guān)聯(lián)公司——中國移動、聯(lián)通

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-tMAmvfki-1648124617811)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324103923767.png)]

第二章 靜態(tài)代理

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-2P1WTaWK-1648124617811)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324104224384.png)]

2.1 實現(xiàn)靜態(tài)代理的方式

2.1.1 靜態(tài)代理

1)代理類是自己手工實現(xiàn)的,自己創(chuàng)建一個java類,表示代理類

2)同時你所要代理的目標(biāo)

  • 特點:1.實現(xiàn)簡單

? 2.容易理解

  • 案例一:模擬一個用戶購買u盤的行為。

    用戶:客戶端類
    商家:代理,代理某個品牌的u盤。
    廠家:目標(biāo)類。
    三者的關(guān)系:用戶(客戶端)-—-商家(代理)-—-廠家(目標(biāo))
    商家和廠家都是賣u盤的,他們完成的功能是一致的,都是賣u盤。

2.1.2 實現(xiàn)步驟

1.創(chuàng)建一個接口,定義賣u盤的方法,表示你的廠家和商家做的事情
2.創(chuàng)建廠家類,實現(xiàn)1步驟的接口
3.創(chuàng)建商家,就是代理,也需要實現(xiàn)1步驟中的接口
4.創(chuàng)建客戶端類,調(diào)用商家的方法買一個u盤

2.3 具體實現(xiàn)

[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-omhUDZHI-1648124617812)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324111535407.png)]

1.創(chuàng)建一個接口,定義賣u盤的方法,表示廠家和商家做的事情

package com.gz.service;public interface UsbSell {/*** 定義一個方法 參數(shù) amount:表示一次購買的數(shù)量,暫時不用* 返回值表示一個u盤的價格* @param* @return*/float sell(int amount); }

2.創(chuàng)建廠家類,實現(xiàn)1的接口

package com.gz.factory;import com.gz.service.UsbSell;//目標(biāo)類:金士頓廠家,不接受用戶的單獨購買 public class UsbKinFactory implements UsbSell {@Overridepublic float sell(int count) {//一個128G的U盤是85元.//后期根據(jù)amount,可以實現(xiàn)不同的價格,例如10000個,單價是80,50000個75return 85.0f;} }

3.創(chuàng)建商家(代理),也需要實現(xiàn)1接口

package com.gz.shangjia;import com.gz.factory.UsbKinFactory; import com.gz.service.UsbSell; //淘寶是一個商家,代理金士頓U盤的銷售 public class TaoBaoKin implements UsbSell {// 聲明 商家代理的廠家具體是誰private UsbKinFactory factory = new UsbKinFactory();// 實現(xiàn)銷售U盤功能@Overridepublic float sell(int amount) {// 向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨// 發(fā)送給工廠,我需要的訂單,返回報價float money = factory.sell(amount);// 商家需要加價也就是代理要增加價格money = money + 20;//在目標(biāo)類的方法調(diào)用后,你做的其他功能,都是增強的意思System.out.println("給用戶一個返現(xiàn)紅包");//功能增強,商家加價賣出,或者給用戶返現(xiàn)紅包return money;} }

4.創(chuàng)建客戶類,調(diào)用商家的方法買U盤

package com.gz;import com.gz.shangjia.TaoBaoKin; import com.gz.shangjia.WeiShang;public class Main {public static void main(String[] args) {// write your code here// 創(chuàng)建代理的商家淘寶對象TaoBaoKin taoBaoKin = new TaoBaoKin();// 我只向淘寶買一件產(chǎn)品,得到報價float money = taoBaoKin.sell(1);System.out.println("淘寶買一個金士頓U盤價格:"+money);WeiShang weiShang = new WeiShang();float sell = weiShang.sell(1);System.out.println("微商買一個金士頓U盤價格:"+sell);} }

2.4 使用代理的作用

  • 功能增強:在你原有的功能上,增加了額外的功能.新增加的功能,叫做功能增強
  • 控制訪問:代理類不讓你訪問目標(biāo),例如商家不讓用戶訪問廠家
  • 2.5靜態(tài)代理的優(yōu)缺點

    • 優(yōu)點:

    • 實現(xiàn)簡單
    • 容易簡單
    • 缺點:當(dāng)你的項目中,目標(biāo)類的代理類很多的時候,有一下的缺點

    • 當(dāng)目標(biāo)類增加了,代理類可能也需要成倍的增加

      [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BUP9M6lk-1648124617813)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324112348643.png)]

    • 當(dāng)你的接口中功能在增加了,或者修改了,會影響眾多的實現(xiàn)類,廠家類,代理都需要修改,影響比較多.

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-E2Zpdibs-1648124617814)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324112253369.png)]

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-vO8F9rVw-1648124617816)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324112423290.png)]

    第三章 動態(tài)代理

    2.1 靜態(tài)和動態(tài)模式的對比

    在靜態(tài)代理中目標(biāo)很多的時候,可以使用動態(tài)代理,避免靜態(tài)代理的缺點

    在靜態(tài)代理中目標(biāo)類很多時候,可以使用動態(tài)代理,避免靜態(tài)代理的缺點。

    • 動態(tài)代理的特點:

    • 動態(tài)代理中目標(biāo)類即使很多,代理類數(shù)量可以很少
    • 當(dāng)你修改了接口中的方法時,不會影響代理類。
    • 動態(tài)代理的作用:

    在程序執(zhí)行過程中,使用jdk的反射機制,創(chuàng)建代理類對象,并動態(tài)的指定要代理目標(biāo)類。換句話說:動態(tài)代理是一種創(chuàng)建java象的能力,讓你不用創(chuàng)建 TaoBao類就能創(chuàng)建代理類對象,除去了中間商,在java中,要想創(chuàng)建對象就必須:

  • 創(chuàng)建類文件,java 文件編譯為class
  • 使用構(gòu)造方法,創(chuàng)建類的對象
  • 2.2 動態(tài)代理的介紹

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-yKQcbMDD-1648124617817)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324184245436.png)]

  • 動態(tài)代理是指代理類對象在程序運行時由JVM根據(jù)反射機制動態(tài)生成的。動態(tài)代理不需要定義代理類的,java源文件。
  • 動態(tài)代理其實就是jdk運行期間,動態(tài)創(chuàng)建class字節(jié)碼并加載到JVM。
  • 動態(tài)代理的實現(xiàn)方式常用的有兩種:使用JDK代理,與通過CGLlB動態(tài)代理。
  • 動態(tài)代理的實現(xiàn):

  • jdk動態(tài)代理(理解):使用java反射包中的類和接口實現(xiàn)動態(tài)代理的功能,反射包java.lang.reflect,里面有三個類:InvocationHandler,Method,Proxy
  • cglib動態(tài)代理(了解): cglib是第三方的工具庫,創(chuàng)建代理對象
  • cglib的原理是繼承,cglib通過繼承目標(biāo)類,創(chuàng)建它的子類,在子類中重寫父類中同名的方法,實現(xiàn)功能的修改。
  • 因為cglib是繼承,重寫方法,所以要求目標(biāo)類不能是fina1的,方法也不能是final的。cglib的要求目標(biāo)類比較寬松,只要能繼承就可以了。cglib在很多的框架中使用,比如mybatis,spring框架中都有使用。
  • 2.3 JDK動態(tài)代理

    jdk動態(tài)代理:
    1.反射, Method類,表示方法。類中的方法。通過Method可以執(zhí)行某個方法

    2.jdk動態(tài)代理的實現(xiàn)
    反射包java.lang. reflect,里面有三個類:InvocationHandler,Method,Proxy

    2.3.1 Interface InvocationHandler

    public interface InvocationHandler

    InvocationHandler是由代理實例的調(diào)用處理程序?qū)崿F(xiàn)的接口 。
    每個代理實例都有一個關(guān)聯(lián)的調(diào)用處理程序。 當(dāng)在代理實例上調(diào)用方法時,方法調(diào)用將被編碼并分派到其調(diào)用處理程序的invoke方法。

    1)InvocationHandler接口(調(diào)用處理器):就一個方法 invoke()
    ? invoke():表示代理對象要執(zhí)行的功能代碼。你的代理類要完成的功能就寫在invoke()方法中。

    • 代理類完成的功能
    • 調(diào)用目標(biāo)方法,執(zhí)行目標(biāo)方法的功能
    • 功能增強,在目標(biāo)方法調(diào)用時,增加功能

    方法原型:

    參數(shù):object proxy:jdk創(chuàng)建的代理對象,無需賦值。Method method:目標(biāo)類中的方法,jdk提供method對象的object[]args:目標(biāo)類中方法的參數(shù),jdk提供的。 Object invoke(Object proxy,方法 method,Object[] args)throws Throwable處理代理實例上的方法調(diào)用并返回結(jié)果。

    2.3.2 Method類

    2)Method類:表示方法的,確切的說就是目標(biāo)類中的方法。
    作用:通過 Method可以執(zhí)行某個目標(biāo)類的方法, method. invoke(目標(biāo)對象,方法的參數(shù));

    object ret= method. invoke(service22,"李四")

    說明:method.invoke()就是為了用來執(zhí)行目標(biāo)方法的,等同于靜態(tài)代理中的

    // 向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨// 發(fā)送給工廠,我需要的訂單,返回報價float price = factory.sell(amount);

    2.3.3 Proxy類

    3)proxy類:核心的對象,創(chuàng)建代理對象。之前創(chuàng)建對象都是new類的構(gòu)造方法()
    現(xiàn)在我們是使用proxy類的方法,代替new的使用。
    方法:靜態(tài)方法 newProxyInstance();
    作用:創(chuàng)建代理對象,等同于靜態(tài)代理中的TaoBao taoBao=new TaoBao()

    我們來觀察方法原型

    public static Object newProxyInstance( ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException

    參數(shù)含義:

  • ClassLoader loader 類加載器,負(fù)責(zé)向內(nèi)存中加載對象的,使用反射機制獲取對象的ClassLoader,如何獲取? 類 a, a.getCalss().getClassLoader(),目標(biāo)對象的類加載器。

    這里我們細(xì)分:每一個類都繼承Object類,在Object中有一個getClass方法,表示 類對象的運行時類的Class對象。 而Class類里面有一個public ClassLoader getClassLoader()方法

  • Class<?>[] interfaces: 接口,目標(biāo)對象實現(xiàn)的接口,也是反射獲取的

  • InvocationHandler h : 我們自己寫的,代理類要完成的功能

  • 返回值:也就是代理對象

    第四章 實現(xiàn)動態(tài)代理步驟

  • 創(chuàng)建接口,定義目標(biāo)類要完成的功能
  • 創(chuàng)建目標(biāo)類實現(xiàn)接口
  • 創(chuàng)建InvocationHandler接口的實現(xiàn)類,在invoke()方法中完成代理類的功能
  • 調(diào)用目標(biāo)方法
  • 增強功能
  • 使用Proxy類的靜態(tài)方法,創(chuàng)建代理對象,并把返回值轉(zhuǎn)換成接口類型
  • 第一步:創(chuàng)建接口,定義目標(biāo)所需功能

    public interface UsbSell {float sell(int amount); }

    第二步:創(chuàng)建目標(biāo)類實現(xiàn)接口

    public class UsbKingFactory implements UsbSell {@Overridepublic float sell(int amount) {System.out.println("目標(biāo)類中,執(zhí)行了sell目標(biāo)方法");return 85.02f;} }

    我們寫了接口類,定義了功能,寫了代理類,實現(xiàn)了接口功能,按照以前的操作,現(xiàn)在就需要寫一個真正的代理類,創(chuàng)建對象.

    第三步:創(chuàng)建Invocationhandler實現(xiàn)類

    1.調(diào)用目標(biāo)的方法

    2.增強功能

    public class MyHandle implements InvocationHandler {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {return null;} }

    我們就在以前代理類的實現(xiàn)方法上進(jìn)行修改

    //之前的代理類public class TaoBao implements usbSell {// 聲明 商家代理的廠家具體是誰private UsbKingFactory factory =new UsbKingFactory();@Override// 實現(xiàn)銷售U盤功能public float sell(int amount) {// 向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨// 發(fā)送給工廠,我需要的訂單,返回報價float price = factory.sell(amount);// 商家需要加價也就是代理要增加價格price = price + 25;//在目標(biāo)類的方法調(diào)用后,你做的其他功能,都是增強的意思System.out.println("淘寶再給你返回一個優(yōu)惠券,或者紅包");// 增加的價格return price;}}

    調(diào)用目標(biāo)的方法

    //傳入是誰的對象,就給誰創(chuàng)建代理public MyHandle(Object target) {this.target = target;} invoke里面的設(shè)置Object res =null;// 向廠家發(fā)送訂單,告訴廠家,我買了U盤,廠家發(fā)貨// 發(fā)送給工廠,我需要的訂單,返回報價 // float price = factory.sell(amount);res = method.invoke(target,args); //待執(zhí)行目標(biāo)方法,執(zhí)行后返回值

    第四步:創(chuàng)建代理對象,并把返回值轉(zhuǎn)換成接口類型

    public class MainShop {public static void main(String[] args){ // 1.創(chuàng)建對象,使用Proxy // 2.創(chuàng)建目標(biāo)對象UsbSell factory = new UsbKingFactory(); // 3.創(chuàng)建Invocationhandler對象InvocationHandler myHandle = new MyHandle(factory);// 4.創(chuàng)建代理對象UsbSell proxy = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(),myHandle); // 通過代理執(zhí)行方法float price = proxy.sell(1);System.out.println("通過動態(tài)代理對象,調(diào)用方法:" +price);} }

    執(zhí)行成功.和之前動態(tài)代理模式一樣

    第五章 動態(tài)代理的執(zhí)行流程

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-NaxR9YCD-1648124617818)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324192011783.png)]

    5.1 執(zhí)行流程

  • 當(dāng)執(zhí)行poxy.sell(1)時候調(diào)用的是哪里呢?是執(zhí)行我們的proxy在創(chuàng)建時,指定的這個handler他里面的invoke()方法。(handler里面的invoke()方法的形參)此時sell()會賦給method,參數(shù)1會賦給args

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-0HfCKxBt-1648124617819)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324193917141.png)]

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-P9BqH7C3-1648124617819)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324201643212.png)]

  • 然后就到了invoke()方法里面,之后到了method.invoke(target,args),這里所執(zhí)行的是目標(biāo)類的方法,誰把target傳給了invoke就執(zhí)行誰的方法。這里我們傳的是目標(biāo)類,因此他會去調(diào)用目標(biāo)類中的方法,目標(biāo)類方法執(zhí)行完成之后會有一個返回值,返回給調(diào)用目標(biāo)類的方法

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-mWR7mUHx-1648124617820)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324201421415.png)]

    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-f9RzUga5-1648124617821)(C:\Users\Dell\AppData\Roaming\Typora\typora-user-images\image-20220324201852500.png)]

  • 然后hadler里面的invoke方法結(jié)束之后,會返回一個值給客戶端的proxy.sell()方法

  • 5.2 動態(tài)代理模板

  • 創(chuàng)建目標(biāo)對象 接口類 目標(biāo)類對象 =new 目標(biāo)類();
  • 創(chuàng)建InvocationHandler對象InvocationHandler handler = new MySellHandler(接口類對象);
  • 創(chuàng)建代理對象接口類 proxy = (接口類) Proxy.newProxyInstance(factory.getClass().getClassLoader(), factory.getClass().getInterfaces(),handler);
  • 通過代理執(zhí)行方法proxy.方法();
  • 第六章 項目中的應(yīng)用

    我們需要知道代理能做什么?

    在不改變原來目標(biāo)方法功能的前提下,可以在代理中增強自己的功能代碼,程序開發(fā)中的意思,

    比如:你所在的項目,有一個功能是其他人(公司其他部門,其他小組的人)寫好的,你可以使用

    //比如,同事開發(fā)一個GoNong類 GoNong.class , GoNong gn=new GoNong()//我們需要增加一個print方法

    我們發(fā)現(xiàn)這個功能現(xiàn)在還存在缺點,不能完全滿足我項目的需要,我需要在print()執(zhí)行過后,需要自己再增加代理,使用什么方法那,肯定是代理,因為別人不會讓我們看源文件

    執(zhí)行步驟:

    1.我們先建立一個接口功能,很簡單的一個功能

    public interface HelloService {/*** 打印報表,報表* @param name* @return*/int print (String name); }

    2.我們再加個接口實現(xiàn)類

    public class GoNeng implements HelloService {@Overridepublic int print(String name) {System.out.println("其他人寫好的這個方法!");return 2;} }

    3.我們?nèi)绻鄬ι鲜龉δ苓M(jìn)行修改,我們不可能直接去在原方法上進(jìn)行修改

    我們設(shè)置一個類來使用這個接口

    public class MyApp {public static void main(String[] args){GoNeng gn = new GoNeng();int i = gn.print("nihao1");System.out.println("num" +i);} }

    問題是如果我們想修改這個功能改怎么辦?在不修改源代碼的基礎(chǔ)上,我們可以創(chuàng)建一個代理類,來增強這個類方法,

    3.設(shè)置一個代理類實現(xiàn)功能的增強和代理

    public class MyInvocationHandler implements InvocationHandler {private Object target=null;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 調(diào)用目標(biāo)方法,執(zhí)行print()得到2Object res = method.invoke(target,args); //返回為2的結(jié)果//我們可以把結(jié)果再乘以2if (res!=null){Integer num = (Integer) res;res = num*2; }return null;} }

    5.我們?nèi)曰氐街鞣椒ɡ锩孢M(jìn)行測試

    public class MyApp {public static void main(String[] args){ // GoNeng gn = new GoNeng(); // int i = gn.print("nihao1"); // System.out.println("num" +i);GoNeng goNeng = new GoNeng();InvocationHandler handler = new MyInvocationHandler(goNeng);HelloService proxy = (HelloService) Proxy.newProxyInstance(goNeng.getClass().getClassLoader(), goNeng.getClass().getInterfaces(),handler);int num = proxy.print("市場");System.out.println("我們期望得到的 num =="+num);} }

    測試System.out.println("動態(tài)代理類參數(shù)接口"+goNeng.getClass().getInterfaces()[0].getName());

    動態(tài)代理類參數(shù)接口com.rango.service.HelloService 其他人寫好的這個方法! 我們期望得到的 num ==4

    完結(jié)

    動態(tài)代理,必須要有接口出現(xiàn),如果沒有,我們可以使用cglib實現(xiàn)

    總結(jié)

    以上是生活随笔為你收集整理的JDK动态代理模式这篇就够了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。