麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

黑馬程序員——【Java高新技術(shù)】——代理

2019-11-14 21:18:40
字體:
供稿:網(wǎng)友
黑馬程序員——【java高新技術(shù)】——代理

---------- android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------

一、“代理概述”及“AOP概念”

  (一)代理概述

  1、問題:要為已存在的多個具有相同接口的目標(biāo)類的各個方法增加一些系統(tǒng)功能,例如,異常處理、日志、計算方法的運行時間、事務(wù)管理等等,如何去做?

  解答:編寫一個與目標(biāo)類具有相同接口的代理類,代理類的每個方法調(diào)用目標(biāo)類的相同方法,并在調(diào)用方法時加上系統(tǒng)功能的代碼。

  2、代理原理圖,如下:

  

  3、代理的優(yōu)點

  如果采用工廠模式和配置文件的方式進行管理,則不需要修改客戶端程序,在配置文件中配置是使用目標(biāo)類、還是代理類,這樣以后很容易切換。例如,想要日志功能時就配置代理類,否則配置目標(biāo)類,這樣,增加系統(tǒng)功能很容易,以后運行一段時間后,又想去掉系統(tǒng)功能也很容易。

  (二)AOP概念

  1、問題引入:

  (1)系統(tǒng)中存在交叉業(yè)務(wù),一個交叉業(yè)務(wù)就是要切入到系統(tǒng)中的一個方面,如下所示:

             安全 事務(wù) 日志

  StudentService ———|——————|——————|—————

  CourseService ———|——————|——————|—————

  MiscService ———|——————|——————|—————

  (2)用具體的程序代碼描述交叉業(yè)務(wù):

  method1 method2 method3

  { { {

  ------------------------------------------切面

  .... .... ......

  ------------------------------------------切面

  } } }

  2、AOP概念

  (1)定義:交叉業(yè)務(wù)的編程問題即為面向方面的編程(aspect oriented PRogram ,簡稱AOP),AOP的目標(biāo)就是要使交叉業(yè)務(wù)模塊化。

  (2)可以采用將切面代碼移動到原始方法的周圍,這與直接在方法中編寫切面代碼的運行效果是一樣的,如下所示:

  ----------------------------------------切面

  func1 func2 func3

  { { {

  .... .... ....

  } } }

  -----------------------------------------切面

  總結(jié):(1)使用代理技術(shù)正好可以解決這種交叉業(yè)務(wù)模塊化的問題,代理是實現(xiàn)AOP功能的核心和關(guān)鍵技術(shù)。(2)安全,事務(wù),日志等功能要貫穿到好多個模塊中,所以,它們就是交叉業(yè)務(wù)。

二、動態(tài)代理技術(shù)

  1、手動增加代理類存在的問題?

  要為系統(tǒng)中的各種接口的類增加代理功能,則需要太多的代理類,全部采用靜態(tài)代理方式,就要寫成百上千個代理類,將是一件工作量巨大且非常麻煩的事情。

  2、如何解決上述存在的問題?

  JVM可以在“運行期”動態(tài)生成出類的字節(jié)碼,這種動態(tài)生成的類往往被用作代理類,即動態(tài)代理類。

  3、動態(tài)類需注意細節(jié):

  JVM生成的動態(tài)類必須實現(xiàn)一個或多個接口,這樣JVM就知道該實現(xiàn)什么方法。所以,JVM生成的動態(tài)類只能用作具有相同接口的目標(biāo)類的代理。

  4、如果一個目標(biāo)類自身沒有實現(xiàn)接口,如何讓JVM動態(tài)生成的代理類與目標(biāo)類有相同的方法列表呢?

  生成的代理類的方法聲明要不要和目標(biāo)類的方法一樣?要。但目標(biāo)類自身并沒有實現(xiàn)接口,那通過什么樣的方式告訴JVM生成的代理類與目標(biāo)類有相同的方法列表,JVM干不了這件事情,因為沒接口。

  這時候有一個第三方CGLIB庫,CGLIB庫可以動態(tài)生成一個類的子類,一個類的子類也可以用作該類的代理,所以,如果要為一個沒有實現(xiàn)接口的類生成動態(tài)代理類,那么可以使用CGLIB庫。

  5、在代理方法中什么位置可以插入系統(tǒng)功能代碼?

  代理類的各個方法中通常除了要調(diào)用目標(biāo)的相應(yīng)方法和對外返回目標(biāo)返回的結(jié)果外,還可以在代理方法中的如下四個位置加上系統(tǒng)功能代碼:

  (1)在調(diào)用目標(biāo)方法之前

  (2)在調(diào)用目標(biāo)方法之后

  (3)在調(diào)用目標(biāo)方法前后

  (4)在處理目標(biāo)方法異常的catch塊中

三、JVM動態(tài)生成的類

  (一)創(chuàng)建動態(tài)類及查看其方法列表信息

  1、要求:

  (1)創(chuàng)建實現(xiàn)了Collection接口的動態(tài)類和查看其名稱,分析Proxy.getProxyClass方法的各個參數(shù)。

  (2)編碼列出動態(tài)類中的所有構(gòu)造方法和參數(shù)簽名

  (3)編碼列出動態(tài)類中的所有方法和參數(shù)簽名

  2、示例代碼:

 1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.Method; 3 import java.lang.reflect.Proxy; 4 import java.util.Collection; 5 public class ProxyTest { 6     /** 7      * @param args 8      * @throws SecurityException 9      * @throws NoSuchMethodException10      * @throws Exception11      * @throws IllegalArgumentException12      * @throws IllegalaccessException13      * @throws InstantiationException14      */15     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, Exception {16         Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);17         System.out.println(clazzProxy1.getName());18         19         System.out.println("------------begin constructor list ------------");20         Constructor[] constructors = clazzProxy1.getConstructors();21         for(Constructor constructor : constructors){22             String name = constructor.getName();23             StringBuilder sb = new StringBuilder(name);24             sb.append("(");25             Class[] clazzParams = constructor.getParameterTypes();26             for(Class clazzParam : clazzParams ){27                 sb.append(clazzParam.getName()).append(",");28             }29             if( clazzParams!=null && clazzParams.length!=0)30                 sb.deleteCharAt(sb.length()-1);31             sb.append(")");32             System.out.println(sb);33         }34         35         System.out.println("------------begin method list -------------");36         Method[] methods = clazzProxy1.getMethods();37         for(Method method : methods){38             String name = method.getName();39             StringBuilder sb = new StringBuilder(name);40             sb.append("(");41             Class[] clazzParams = method.getParameterTypes();42             for(Class clazzParam : clazzParams ){43                 sb.append(clazzParam.getName()).append(",");44             }45             if( clazzParams!=null && clazzParams.length!=0)46                 sb.deleteCharAt(sb.length()-1);47             sb.append(")");48             System.out.println(sb);49         }50     }51 }

  (二)創(chuàng)建動態(tài)類的實例對象及調(diào)用其方法

  1、創(chuàng)建動態(tài)類的實例對象有三種方式:

  (1)首先通過Proxy類的getProxyClass(ClassLoader loader, Class<?>... interfaces)方法,獲取代理類的對象;然后通過反射獲得構(gòu)造方法;最后通過接口InvocationHandler的子類創(chuàng)建對象;

  (2)首先通過Proxy類的getProxyClass(ClassLoader loader, Class<?>... interfaces)方法,獲取代理類的對象;通過反射獲得構(gòu)造方法;通過給構(gòu)造方法的newInstance()傳入InvocationHandler的匿名內(nèi)部類來創(chuàng)建對象;

  (3)直接通過Proxy類的newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)方法,創(chuàng)建對象。

  2、創(chuàng)建動態(tài)類的實例對象的代碼實現(xiàn)

 1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.util.ArrayList; 6 import java.util.Collection; 7 public class ProxyTest { 8     /** 9      * @param args10      * @throws SecurityException11      * @throws NoSuchMethodException12      * @throws Exception13      * @throws IllegalArgumentException14      * @throws IllegalAccessException15      * @throws InstantiationException16      */17     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, Exception {18         Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);19         Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);20 21         System.out.println("------------begin create instance list --------------");22         //System.out.println("------------方式一:創(chuàng)建動態(tài)類的實例對象 ----------");23         class MyInvocationHandler1 implements InvocationHandler{24             @Override25             public Object invoke(Object proxy, Method method, Object[] args)26                     throws Throwable {27                 // TODO Auto-generated method stub28                 return null;29             }30         }31         Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler1());32         System.out.println(proxy1);33 34         // System.out.println("------------方式二:創(chuàng)建動態(tài)類的實例對象 -----------");35         Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){36             @Override37             public Object invoke(Object proxy, Method method, Object[] args)38                     throws Throwable {39                 // TODO Auto-generated method stub40                 return null;41             }42         });43 44         // System.out.println("------------方式三:創(chuàng)建動態(tài)類的實例對象 ------------");45         Collection proxy3 = (Collection)Proxy.newProxyInstance(46                 Collection.class.getClassLoader(),47                 new Class[]{Collection.class},48                 new InvocationHandler(){49                     ArrayList target = new ArrayList();50                     @Override51                     public Object invoke(Object proxy, Method method,52                             Object[] args) throws Throwable {53                         long beginTime = System.currentTimeMillis();54                         Object retVal = method.invoke(target, args);55                         long endTime = System.currentTimeMillis();56                         System.out.println(method.getName()+"run time"+(endTime-beginTime));57                         return retVal;58                     }59                 }60                 );61         proxy3.add("zxx");62         proxy3.add("flx");63         proxy3.add("lhm");64         proxy3.add("bxd");65         proxy3.add("yzz");        66         System.out.println(proxy3.size());67     }68 }

  (三)總結(jié)思考

  問題:讓JVM創(chuàng)建動態(tài)類及其實例對象,需要給它提供哪些信息?

  解答:主要包括三個方面的信息:

  (1)生成的類中有哪些方法,通過讓其實現(xiàn)哪些接口的方式進行告知;

  (2)產(chǎn)生的類字節(jié)碼必須有個一個關(guān)聯(lián)的類加載器對象;

  (3)生成的類中的方法的代碼是怎樣的,也得由我們提供。把我們的代碼寫在一個約定好了接口對象的方法中,把對象傳給它,它調(diào)用我的方法,即相當(dāng)于插入了我的代碼。提供執(zhí)行代碼的對象就是那個InvocationHandler對象,它是在創(chuàng)建動態(tài)類的實例對象的構(gòu)造方法時傳遞進去的。在上面的InvocationHandler對象的invoke方法中加一點代碼,就可以看到這些代碼被調(diào)用運行了。

  * 用Proxy.newInstance方法直接一步就創(chuàng)建出代理對象。

四、動態(tài)生成的類的內(nèi)部代碼分析

  在上面“創(chuàng)建動態(tài)類的實例對象”的代碼中,動態(tài)生成的類實現(xiàn)了Collection接口(可以實現(xiàn)若干接口),生成的類有Collection接口中的所有方法和一個如下接受InvocationHandler參數(shù)的構(gòu)造方法。

  1、問題:構(gòu)造方法接受一個InvocationHandler對象,接收這個對象要干什么用呢?該方法內(nèi)部的代碼是怎樣的呢?

  (1)構(gòu)造方法接收一個參數(shù),為了記住這個參數(shù),以后運用它。

  (2)內(nèi)部代碼:

1 $Proxy0 implements Collection{2     InvocationHandler handler;3     public $Proxy0(InvocationHandler handler){4         this.handler = handler;5     }6 }

  2、問題:實現(xiàn)Collection接口的動態(tài)類中的各個方法的代碼又是怎樣的呢? InvocationHandler接口中定義的invoke方法接收的三個參數(shù)又是什么意思?

 1 (1)$Proxy0 implements Collection{ 2     InvocationHandler handler; 3     public $Proxy0(InvocationHandler handler){ 4         this.handler = handler; 5     } 6     //生成的Collection接口中的方法的運行原理 7     int size(){ 8         return handler.invoke(this, this.getClass().getMethod("size"), null); 9     }10     void clear(){11         handler.invoke(this, this.getClass().getMethod("clear"), null);12     }13     boolean add(Object obj){14         handler.invoke(this, this.getClass().getMethod("add"), obj);15     }16 }

  (2)InvocationHandler接口中定義的invoke方法接收的三個參數(shù)意義,如下圖說明:

  

  說明:客戶端調(diào)用了代理對象objProxy,調(diào)用了代理對象的add()方法,為該方法傳遞了字符串參數(shù)"abc"。

  3、為什么動態(tài)類的實例對象的getClass()方法返回了正確結(jié)果呢?

  調(diào)用調(diào)用代理對象的從Object類繼承的hashCode, equals, 或toString這幾個方法時,代理對象將調(diào)用請求轉(zhuǎn)發(fā)給InvocationHandler對象,對于其他方法,則不轉(zhuǎn)發(fā)調(diào)用請求。

五、動態(tài)生成的類成為目標(biāo)類的代理

  1、動態(tài)代理的工作原理圖

  

  2、eclipse重構(gòu)出一個getProxy方法綁定接收目標(biāo)同時返回代理對象,怎樣將目標(biāo)類作為參數(shù)傳進去?

  (1)直接在InvocationHandler實現(xiàn)類中創(chuàng)建目標(biāo)類的實例對象,可以看運行效果和加入日志代碼,但沒有實際意義。

  (2)為InvocationHandler實現(xiàn)類注入目標(biāo)類的實例對象,不能采用匿名內(nèi)部類的形式了。

  (3)讓匿名的InvocationHandler實現(xiàn)類訪問外面方法中的目標(biāo)類實例對象的final類型的引用變量。

  3、在上面將目標(biāo)類作為參數(shù)傳入之后,將系統(tǒng)功能代碼模塊化,即將切面代碼也改為通過參數(shù)形式提供,怎樣把要執(zhí)行的系統(tǒng)功能代碼以參數(shù)形式提供?

  (1)把要執(zhí)行的代碼裝到一個對象的某個方法里,然后把這個對象作為參數(shù)傳遞,接收者只要調(diào)用這個對象的方法,即等于執(zhí)行了外界提供的代碼!

  (2)為bind方法增加一個Advice參數(shù)。

  4、將目標(biāo)類和系統(tǒng)功能作為參數(shù)傳遞給getProxy()方法,實現(xiàn)示例代碼如下:

  (1)創(chuàng)建ProxyTest類

 1 import java.lang.reflect.Constructor; 2 import java.lang.reflect.InvocationHandler; 3 import java.lang.reflect.Method; 4 import java.lang.reflect.Proxy; 5 import java.util.ArrayList; 6 import java.util.Collection; 7 public class ProxyTest { 8     /** @param args 9      * @throws SecurityException10      * @throws NoSuchMethodException11      * @throws Exception 12      * @throws IllegalArgumentException13      * @throws IllegalAccessException14      * @throws InstantiationException15      */16     public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, Exception {17         final ArrayList target = new ArrayList();//將目標(biāo)抽取出來,方法里面的內(nèi)部類要訪問局部變量必須添加final關(guān)鍵字        18         Collection proxy3 = (Collection)getProxy(target,new MyAdvice());//抽取出來的方法19         proxy3.add("zxx");20         proxy3.add("flx");21         proxy3.add("lhm");        22         System.out.println(proxy3.size());23     }24     private static Object getProxy(final Object target,final Advice advice) { /*做成通用的方法,返回Object*/25         Object proxy3 = Proxy.newProxyInstance(26                 /*Collection.class.getClassLoader(),        //第一個參數(shù)*/27                 target.getClass().getClassLoader(),            //    代理類的類加載器與目標(biāo)類的類加載器相同,與目標(biāo)類有關(guān)。28                 29                 /*new Class[]{Collection.class},        //第二個參數(shù)*/30                 target.getClass().getInterfaces(),    //與target實現(xiàn)相同的接口,代理類要實現(xiàn)的接口也是目標(biāo)類實現(xiàn)的接口,與目標(biāo)類有關(guān)31                 32                 new InvocationHandler(){        //第三個參數(shù),33                     @Override34                     public Object invoke(Object proxy, Method method,35                             Object[] args) throws Throwable {36                         /*37                         long beginTime = System.currentTimeMillis();    //將系統(tǒng)功能抽取為一個對象38                         Object retVal = method.invoke(target, args);39                         long endTime = System.currentTimeMillis();    //將系統(tǒng)功能抽取為一個對象                        40                         System.out.println(method.getName()+"run time"+(endTime-beginTime));41                         return retVal;42                         */43                         advice.beforeMethod(method);44                         Object retVal = method.invoke(target, args);45                         advice.afterMethod(method);    46                         return retVal;47                     }48                 }49                 );50         return proxy3;51     }52 }

  (2創(chuàng)建Advice接口

import java.lang.reflect.Method;public interface Advice {    //一般來說,這個建議的接口應(yīng)該有四個方法,這四個方法可以分別插入:    /* 代理類的各個方法中通常除了要調(diào)用目標(biāo)的相應(yīng)方法和對外返回目標(biāo)返回的結(jié)果外,     * 還可以在代理方法中的如下四個位置加上系統(tǒng)功能代碼:     *    1.在調(diào)用目標(biāo)方法之前     *    2.在調(diào)用目標(biāo)方法之后     *    3.在調(diào)用目標(biāo)方法前后     *    4.在處理目標(biāo)方法異常的catch塊中      * */    void beforeMethod(Method method);    void afterMethod(Method method);    }

  (3)創(chuàng)建Advice接口的子類MyAdvice

 1 import java.lang.reflect.Method; 2 public class MyAdvice implements Advice { 3     long beginTime = 0; 4     public void beforeMethod(Method method) { 5         // TODO Auto-generated method stub 6         System.out.println("到黑馬程序員訓(xùn)練營來學(xué)習(xí)了!"); 7         beginTime = System.currentTimeMillis();    //將系統(tǒng)功能抽取為一個對象 8     } 9 10     public void afterMethod(Method method) {11         // TODO Auto-generated method stub12         System.out.println("從黑馬程序員訓(xùn)練營畢業(yè)工作了!");13         long endTime = System.currentTimeMillis();    //將系統(tǒng)功能抽取為一個對象    14         System.out.println(method.getName()+" method run of time "+(endTime-beginTime));15         System.out.print(System.lineSeparator() );16     }17 }

六、實現(xiàn)類似spring的可配置的AOP框架

  (一)工廠類BeanFactory

   1、工廠類BeanFactory:負責(zé)創(chuàng)建目標(biāo)類或代理類的實例對象,并通過配置文件實現(xiàn)切換。

   2、getBean方法:根據(jù)參數(shù)字符串返回一個相應(yīng)的實例對象。如果參數(shù)字符串在配置文件中對應(yīng)的類名不是ProxyFactoryBean,則直接返回該類的實例對象,否則返回該類示例對象的getProxy方法返回的對象。

   3、BeanFactory的構(gòu)造方法:接收代表配置文件的輸入流對象的配置文件。

   4、ProxyFactoryBean為BeanFactory提供配置參數(shù)信息:(1)目標(biāo)(target)(2)通告(advice)

   5、BeanFactory和ProxyFactoryBean:

   (1)BeanFactory是一個純粹的bean工程,就是創(chuàng)建bean即相應(yīng)的對象的工廠。

   (2)ProxyfactoryBean是BeanFactory中的一個特殊的Bean,是創(chuàng)建代理的工廠。

  (二)實現(xiàn)類似spring的可配置的AOP框架的思路:

   1、創(chuàng)建BeanFactory類:

   (1)構(gòu)造方法:接受一個配置文件,通過Properties對象加載InputStream流對象。

   (2)創(chuàng)建getBean(String name)方法:根據(jù)類名name,拿到對應(yīng)的類名className。

   (3)根據(jù)類名獲取其字節(jié)碼對象,并創(chuàng)建實例對象bean。

   (4)判斷bean是否是特殊的Bean即ProxyFactoryBean。

    ① 如果是,就要創(chuàng)建代理類,并設(shè)置目標(biāo)(target)和通告(advice),分別得到各自的實例對象,并返回代理類實例對象。

    ② 如果不是在返回Bean對象自己。

   2、創(chuàng)建ProxyFactoryBean類,定義target和advice;定義getProxy()方法,用于創(chuàng)建代理類對象。

   3、創(chuàng)建配置文件config.properties,對配置文件進行配置,配置內(nèi)容如下

    xxx=java.util.ArrayList

    #xxx=cn.itheima.day3.aopframework.ProxyFactoryBean

    xxx.advice=cn.itheima.day3.MyAdvice

    xxx.target=java.util.ArrayList

    注: #表示注釋當(dāng)前行。

   4、作一個測試類:AopFrameworkTest進行測試。

  (三)完整代碼示例

   1、創(chuàng)建BeanFactory類:

package cn.itheima.day3.aopframework;import java.io.IOException;import java.io.InputStream;import java.util.Properties;import cn.itheima.day3.Advice;public class BeanFactory {    Properties props = new Properties();    public BeanFactory(InputStream ips){        try {            props.load(ips);        } catch (IOException e) {            e.printStackTrace();        }    }    public Object getBean(String name){        String className = props.getProperty(name);//根據(jù)類名name,拿到對應(yīng)的類名。        Object bean = null;        try {            Class clazz = Class.forName(className);            bean = clazz.newInstance();        } catch (Exception e) {            e.printStackTrace();        }        if(bean instanceof ProxyFactoryBean){            Object proxy = null;            ProxyFactoryBean ProxyFactoryBean = (ProxyFactoryBean)bean;            try {                Advice advice = (Advice)Class.forName(props.getProperty(name+".advice")).newInstance();                Object target = Class.forName(props.getProperty(name+".target")).newInstance();                ProxyFactoryBean.setAdvice(advice);                ProxyFactoryBean.setTarget(target);                proxy = ProxyFactoryBean.getProxy();            } catch (Exception e) {                e.printStackTrace();            }            return proxy;        }        return bean;    }}

  

  2、創(chuàng)建ProxyFactoryBean類:

 1 package cn.itheima.day3.aopframework; 2  3 import java.lang.reflect.InvocationHandler; 4 import java.lang.reflect.Method; 5 import java.lang.reflect.Proxy; 6 import cn.itheima.day3.Advice; 7 public class ProxyFactoryBean { 8     private Advice advice; 9     private Object target;10     public Advice getAdvice() {11         return advice;12     }13     public void setAdvice(Advice advice) {14         this.advice = advice;15     }16     public Object getTarget() {17         return target;18     }19     public void setTarget(Object target) {20         this.target = target;21     }22     public Object getProxy() {23         Object proxy3 = Proxy.newProxyInstance(                24                 target.getClass().getClassLoader(),    //    代理類的類加載器與目標(biāo)類的類加載器相同,與目標(biāo)類有關(guān)。25                 target.getClass().getInterfaces(),        //與target實現(xiàn)相同的接口,代理類要實現(xiàn)的接口也是目標(biāo)類實現(xiàn)的接口,與目標(biāo)類有關(guān)26                 27                 new InvocationHandler(){    //第三個參數(shù)28                     @Override29                     public Object invoke(Object proxy, Method method,30                             Object[] args) throws Throwable {31                         advice.beforeMethod(method);32                         Object retVal = method.invoke(target, args);33                         advice.afterMethod(method);34                         return retVal;35                     }36                 }37                 );38         return proxy3;39     }40 }

  3、創(chuàng)建配置文件config.properties

xxx=java.util.ArrayList#xxx=cn.itheima.day3.aopframework.ProxyFactoryBeanxxx.advice=cn.itheima.day3.MyAdvicexxx.target=java.util.ArrayList

  4、創(chuàng)建AopFrameworkTest測試類,進行測試:

 1 package cn.itheima.day3.aopframework; 2  3 import java.io.InputStream; 4 public class AopFrameworkTest { 5     /** 6      * @param args 7      */ 8     public static void main(String[] args) { 9         // TODO Auto-generated method stub10         InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");11         Object bean = new BeanFactory(ips).getBean("xxx");12         System.out.println(bean.getClass().getName());13     }14 }

  5、設(shè)計到的接口Advice及其子類MyAdvice

  (1)Advice接口:

1 package cn.itheima.day3;2 import java.lang.reflect.Method;3 public interface Advice {    4     void beforeMethod(Method method);5     void afterMethod(Method method);6 }

  (2)MyAdvice類:

 1 package cn.itheima.day3; 2 import java.lang.reflect.Method; 3 public class MyAdvice implements Advice { 4     long beginTime = 0; 5     public void beforeMethod(Method method) { 6         // TODO Auto-generated method stub 7         System.out.println("到黑馬程序員訓(xùn)練營來學(xué)習(xí)了!"); 8         beginTime = System.currentTimeMillis();    //將系統(tǒng)功能抽取為一個對象 9     }10 11     public void afterMethod(Method method) {12         // TODO Auto-generated method stub13         System.out.println("從黑馬程序員訓(xùn)練營畢業(yè)工作了!");14         long endTime = System.currentTimeMillis();    //將系統(tǒng)功能抽取為一個對象    15         System.out.println(method.getName()+" method run of time "+(endTime-beginTime));16         System.out.print(System.lineSeparator() );17     }18 }

---------- android培訓(xùn)、java培訓(xùn)、期待與您交流! ----------


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 日本教室三级在线看 | 成人三级电影网址 | 九色在线78m | 免费黄色大片在线观看 | 成人毛片网站 | v片在线看 | 国产一级毛片网站 | 国产免费一区二区三区视频 | 欧产日产国产精品v | 久久亚洲国产精品 | 国产1区在线观看 | 免费成人 | 91免费视频版 | 国产在线一区二区三区 | 国内免费视频成人精品 | 国产精品亚洲欧美一级在线 | av在线播放免费 | 国产成人高清成人av片在线看 | 天堂成人国产精品一区 | 久久久综合视频 | 精品免费国产一区二区三区 | 久久久久国产成人免费精品免费 | 九九热视频在线免费观看 | 成人短视频在线播放 | 精品一区二区三区在线观看视频 | 久久久久久久久日本理论电影 | 国产1区在线 | 免费观看一区 | 日韩精品一二三 | 国产在线导航 | 久久国产一级 | 激情亚洲一区二区三区 | 九九夜夜| 国产毛片视频 | 毛片在线免费播放 | 爱福利视频 | 极品国产91在线网站 | 久久久久北条麻妃免费看 | 九色一区二区 | 88xx成人精品视频 | 免费看成年人视频在线 |