最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解使用Java原生代理實(shí)現(xiàn)AOP實(shí)例

 更新時(shí)間:2017年01月09日 08:59:37   作者:Accelerator__  
本篇文章主要介紹了詳解使用Java原生代理實(shí)現(xiàn)AOP實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下。

一說(shuō)到AOP,大家一定會(huì)想到spring,因?yàn)檫@東西實(shí)在是太強(qiáng)大了.但是大家一定要清楚,AOP是一只編程思想,而Spring僅僅是AOP的一種實(shí)現(xiàn)罷了.

首先百度下:

在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過(guò)預(yù)編譯方式和運(yùn)行期動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)。AOP是OOP的延續(xù),是軟件開發(fā)中的一個(gè)熱點(diǎn),也是Spring框架中的一個(gè)重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對(duì)業(yè)務(wù)邏輯的各個(gè)部分進(jìn)行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時(shí)提高了開發(fā)的效率。

今天呢,咱們就一起用Java原生代理實(shí)現(xiàn)簡(jiǎn)單的AOP功能.

首先,你得需要了解基本的反射知識(shí),否則可能會(huì)感到困惑.

不羅嗦了,直接開始擼碼

首先,咱們先寫一個(gè)簡(jiǎn)單的接口.名字叫AnimalInterface,用來(lái)聲明規(guī)范動(dòng)物的一些基本方法.

這些方法包括 設(shè)置名字,獲取名字,叫聲,屬性(原諒我沒文化,其實(shí)就是獲得是陸棲還是水棲或者水陸兩棲)

package proxy.imp;
public interface AnimalInterface {
  //設(shè)置名字
  void setName(String name);
  //獲取名字
  String getName();
  //叫聲
  void say();
  //獲取棲性
  void getProperty();
}

然后咱們實(shí)現(xiàn)這個(gè)接口,創(chuàng)建一個(gè)名叫小黑的Dog

package proxy;

import proxy.imp.AnimalInterface;
public class DogImp implements AnimalInterface {
  private String name = "小黑";
  public DogImp() {
  }
  @Override
  public void setName(String name) {
    this.name = name;
  }
  @Override
  public String getName() {
    return this.name;
  }
  @Override
  public void say() {
    System.out.println("小狗:汪汪汪汪.....");
  }
  @Override
  public void getProperty() {
    System.out.println("小狗是陸地動(dòng)物,但是會(huì)游泳哦");
  }
}

大家一定迫不及待了,怎么實(shí)現(xiàn)類似AOP的功能呢….

咱們先創(chuàng)建一個(gè)名為AOPHandle的類,讓其實(shí)現(xiàn)InvocationHandler接口,不能使用invoke時(shí)使用proxy作為反射參數(shù)時(shí),因?yàn)榇韺?duì)象的接口,不同于對(duì)象,這種代理機(jī)制是面向接口,而不是面向類的,如果使用proxy,會(huì)造成無(wú)限遞歸.然后就是棧溢出,但是依舊能反射成功一次,這說(shuō)明代理對(duì)象和對(duì)象的代理是不一樣的,但是咱們可以通過(guò)proxy參數(shù)的proxy.getClass()獲得class對(duì)象,然后獲得被代理類的方法和參數(shù),這也為注解注入,特定方法注入,屬性注入提供了一種實(shí)現(xiàn)途徑吧,關(guān)于這個(gè),咱們后面再說(shuō)..

package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class AOPHandle implements InvocationHandler{
  //保存對(duì)象
  private Object o;
  public AOPHandle(Object o) {
    this.o=o;
  }
  /**
   * 這個(gè)方法會(huì)自動(dòng)調(diào)用,Java動(dòng)態(tài)代理機(jī)制
   * 會(huì)傳入下面是個(gè)參數(shù)
   * @param Object proxy 代理對(duì)象的接口,不同于對(duì)象
   * @param Method method 被調(diào)用方法
   * @param Object[] args 方法參數(shù)
   * 不能使用invoke時(shí)使用proxy作為反射參數(shù)時(shí),因?yàn)榇韺?duì)象的接口,不同于對(duì)象
   * 這種代理機(jī)制是面向接口,而不是面向類的
   **/
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //方法返回值
    Object ret=null;
    //打印方法名稱
    System.err.println("執(zhí)行方法:"+method.getName()+"n參數(shù)類型為:");
    //打印參數(shù)
    for(Class type:method.getParameterTypes())
      System.err.println(type.getName());
    //打印返回類型
    System.err.println("返回?cái)?shù)據(jù)類型:"+method.getReturnType().getName());
    //反射調(diào)用方法
    ret=method.invoke(o, args);
    //聲明結(jié)束
    System.err.println("方法執(zhí)行結(jié)束");
    //返回反射調(diào)用方法的返回值
    return ret;
  }
}

動(dòng)態(tài)代理已經(jīng)搞定..然后就是咱們的AnimalFactory了..咱們繼續(xù)

package proxy;
import java.lang.reflect.Proxy;
public class AnimalFactory {
  /***
   * 獲取對(duì)象方法
   * @param obj
   * @return
   */
  private static Object getAnimalBase(Object obj){
    //獲取代理對(duì)象
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
        obj.getClass().getInterfaces(), new AOPHandle(obj));
  }
  /***
   * 獲取對(duì)象方法
   * @param obj
   * @return
   */
  @SuppressWarnings("unchecked")
  public static T getAnimal(Object obj){
    return (T) getAnimalBase(obj);
  }
  /***
   * 獲取對(duì)象方法
   * @param className
   * @return
   */
  @SuppressWarnings("unchecked")
  public static  T getAnimal(String className){
    Object obj=null;
    try {
      obj= getAnimalBase(Class.forName(className).newInstance());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)obj;
  }
  /***
   * 獲取對(duì)象方法
   * @param clz
   * @return
   */
  @SuppressWarnings("unchecked")
  public static  T getAnimal(Class clz){
    Object obj=null;
    try {
      obj= getAnimalBase(clz.newInstance());
    } catch (Exception e) {
      e.printStackTrace();
    }
    return (T)obj;
  }
}

終于到最后了…還差什么呢,大家來(lái)這里看看效果吧…

哈哈…小二,上個(gè)菜..哦~不對(duì),是個(gè)測(cè)試類..哈哈////

package proxy;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import proxy.AnimalFactory;
import proxy.imp.AnimalInterface;

@RunWith(BlockJUnit4ClassRunner.class)
public class AOPTest {

  @Test
  public void Test1() {
    AnimalInterface dog=AnimalFactory.getAnimal(DogImp.class);
    dog.say();
    System.out.println("我的名字是"+dog.getName());
    dog.setName("二狗子");
    System.out.println("我的名字是"+dog.getName());
  }
}

啥?什么,,到了最后說(shuō),,這又卵用,這不是坑爹么?就捕獲一個(gè)這個(gè)玩意,什么用啊…

什么AOP,我怎么一點(diǎn)AOP的影子都沒有看到,怎么切入自定義方法,就一個(gè)syso輸入,往這忽悠觀眾來(lái)了?…..

好吧,那咱們繼續(xù)…看看如何實(shí)現(xiàn)注入自定義方法…

首先增加一個(gè)接口,咱們就稱為AOP注入接口吧.取名AOPMethod哈

創(chuàng)建after和before方法,接收Object proxy, Method method, Object[] args參數(shù)

這樣就能做更多的事情叻…比如執(zhí)行方法前,記錄類狀態(tài),寫入log.監(jiān)控xx變量,,,

開啟你的腦洞吧.

package proxy.imp;
import java.lang.reflect.Method;

public interface AOPMethod{
  //實(shí)例方法執(zhí)行前執(zhí)行的方法
  void after(Object proxy, Method method, Object[] args);
  //實(shí)例方法執(zhí)行后執(zhí)行的方法
  void before(Object proxy, Method method, Object[] args);
}

然后修改AOPHandle類,增加AOPMethod屬性.

在修改構(gòu)造方法,讓在類初始化時(shí)獲得AOPMethod實(shí)例.

最后修改invoke方法….直接上代碼哈

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

import proxy.imp.AOPMethod;

public class AOPHandle implements InvocationHandler{
  //保存對(duì)象
  private AOPMethod method;
  private Object o;
  public AOPHandle(Object o,AOPMethod method) {
    this.o=o;
    this.method=method;
  }
  /**
   * 這個(gè)方法會(huì)自動(dòng)調(diào)用,Java動(dòng)態(tài)代理機(jī)制
   * 會(huì)傳入下面是個(gè)參數(shù)
   * @param Object proxy 代理對(duì)象的接口,不同于對(duì)象
   * @param Method method 被調(diào)用方法
   * @param Object[] args 方法參數(shù)
   * 不能使用invoke時(shí)使用proxy作為反射參數(shù)時(shí),因?yàn)榇韺?duì)象的接口,不同于對(duì)象
   * 這種代理機(jī)制是面向接口,而不是面向類的
   **/
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object ret=null;
    //修改的地方在這里哦
    this.method.before(proxy, method, args);
    ret=method.invoke(o, args);
    //修改的地方在這里哦
    this.method.after(proxy, method, args);
    return ret;
  }
}

呼呼,大功告成,,看起來(lái)一切都么問題,萌萌噠..

趕緊更新下測(cè)試類…

package proxy;

import java.lang.reflect.Method;

import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import proxy.imp.AOPMethod;
import proxy.imp.AnimalInterface;

@RunWith(BlockJUnit4ClassRunner.class)
public class AOPTest {

  public static void main(String[] args) {

    AnimalInterface dog = AnimalFactory.getAnimal(DogImp.class, new AOPMethod() {
      // 這里寫方法執(zhí)行前的AOP切入方法
      public void before(Object proxy, Method method, Object[] args) {
        System.err.println("我在" + method.getName() + "方法執(zhí)行前執(zhí)行");
      }

      // 這里系方法執(zhí)行后的AOP切入方法
      public void after(Object proxy, Method method, Object[] args) {
        System.err.println("我在 " + method.getName() + "方法執(zhí)行后執(zhí)行");

      }
    });
    dog.say();
    String name1="我的名字是" + dog.getName();
    System.out.println(name1);
    dog.setName("二狗子");
    String name2="我的名字是"+dog.getName();
    System.out.println(name2);
  }
}

呼呼,親們,是不是有注入的感覺了?是不是感覺把自己的方法切進(jìn)去了???哈哈….

看起來(lái)一切都已經(jīng)完美了,但是總覺得差了點(diǎn)什么?哦,對(duì),缺少了類似于Spring那么樣的配置文件..

其實(shí)那些已經(jīng)很簡(jiǎn)單了,交給你們?nèi)プ霭?設(shè)計(jì)好XML格式化就妥了,等等,你說(shuō)什么,還不能攔截自定義方法?

不能像Spring那樣攔截自定義方法?oh~~NO,其實(shí)已經(jīng)可以了在before(Object proxy, Method method, Object[] args)中利用method和的給methodName就能做判斷了.

當(dāng)然,本例的并沒有什么實(shí)用意義,更不能個(gè)各種完善的AOP框架相比,本文僅僅為您提供一種思路,但是一定要記住,再牛的東西也是一點(diǎn)點(diǎn)積累出來(lái)的

實(shí)例下載:http://xiazai.jb51.net/201701/yuanma/JavaAOP_jb51.rar

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Spring?Validation接口入?yún)⑿r?yàn)示例代碼

    Spring?Validation接口入?yún)⑿r?yàn)示例代碼

    Spring?Validation是一種用于實(shí)現(xiàn)數(shù)據(jù)校驗(yàn)的框架,它提供了一系列的校驗(yàn)器,針對(duì)不同的數(shù)據(jù)類型可以使用不同的校驗(yàn)器進(jìn)行校驗(yàn),下面這篇文章主要給大家介紹了關(guān)于Spring?Validation接口入?yún)⑿r?yàn)的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • Java中的線程安全問題詳細(xì)解析

    Java中的線程安全問題詳細(xì)解析

    這篇文章主要介紹了Java中的線程安全問題詳細(xì)解析,線程安全是如果有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼,程序每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,此時(shí)我們就稱之為是線程安全的,需要的朋友可以參考下
    2023-11-11
  • SpringBoot無(wú)法連接redis的解決方案

    SpringBoot無(wú)法連接redis的解決方案

    這篇文章主要介紹了SpringBoot無(wú)法連接redis的解決方案,文中通過(guò)代碼示例給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-08-08
  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之健身器材商城系統(tǒng)的實(shí)現(xiàn)

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之健身器材商城系統(tǒng)的實(shí)現(xiàn)

    只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+Jdbc+Servlet+Ajax+Fileupload+mysql實(shí)現(xiàn)健身器材商城系統(tǒng),大家可以在過(guò)程中查缺補(bǔ)漏,提升水平
    2022-03-03
  • 關(guān)于fastjson的常見API詳解

    關(guān)于fastjson的常見API詳解

    這篇文章主要介紹了關(guān)于fastjson的常見API詳解,Fastjson是一個(gè)Java庫(kù),可用于將Java對(duì)象轉(zhuǎn)換為其JSON表示,它還可用于將JSON字符串轉(zhuǎn)換為等效的Java對(duì)象,Fastjson可以處理任意Java對(duì)象,包括您沒有源代碼的預(yù)先存在的對(duì)象,需要的朋友可以參考下
    2023-07-07
  • 關(guān)于SpringBoot獲取IOC容器中注入的Bean(推薦)

    關(guān)于SpringBoot獲取IOC容器中注入的Bean(推薦)

    本文通過(guò)實(shí)例代碼給大家詳解了springboot獲取ioc容器中注入的bean問題,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2018-05-05
  • MyBatis-Plus動(dòng)態(tài)表名的使用

    MyBatis-Plus動(dòng)態(tài)表名的使用

    本文主要介紹了MyBatis-Plus動(dòng)態(tài)表名的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • 詳解Java使用Pipeline對(duì)Redis批量讀寫(hmset&hgetall)

    詳解Java使用Pipeline對(duì)Redis批量讀寫(hmset&hgetall)

    本篇文章主要介紹了Java使用Pipeline對(duì)Redis批量讀寫(hmset&hgetall),具有一定的參考價(jià)值,有興趣的可以了解一下。
    2016-12-12
  • 淺談Springboot整合RocketMQ使用心得

    淺談Springboot整合RocketMQ使用心得

    本篇文章主要介紹了Springboot整合RocketMQ使用心得,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 如何將Java對(duì)象轉(zhuǎn)換為JSON實(shí)例詳解

    如何將Java對(duì)象轉(zhuǎn)換為JSON實(shí)例詳解

    有時(shí)候需要將對(duì)象轉(zhuǎn)換為JSON格式,所以這篇文章主要給大家介紹了關(guān)于如何將Java對(duì)象轉(zhuǎn)換為JSON的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08

最新評(píng)論

德江县| 铁岭县| 五华县| 陇西县| 本溪市| 大港区| 荣成市| 怀远县| 建昌县| 乳山市| 深水埗区| 庄河市| 祁东县| 长治市| 荔波县| 平舆县| 宣威市| 礼泉县| 通州市| 云和县| 宁远县| 潢川县| 呈贡县| 台山市| 赣州市| 安达市| 嵊泗县| 桦川县| 张北县| 本溪市| 巴林右旗| 泽州县| 宜兰市| 湛江市| 六安市| 达拉特旗| 汾阳市| 乐都县| 西畴县| 河南省| 禄劝|