一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 詳解使用Java原生代理實現AOP實例

詳解使用Java原生代理實現AOP實例

2020-07-24 12:27Accelerator__ Java教程

本篇文章主要介紹了詳解使用Java原生代理實現AOP實例,具有一定的參考價值,有興趣的可以了解一下。

一說到AOP,大家一定會想到spring,因為這東西實在是太強大了.但是大家一定要清楚,AOP是一只編程思想,而Spring僅僅是AOP的一種實現罷了.

首先百度下:

在軟件業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。

今天呢,咱們就一起用Java原生代理實現簡單的AOP功能.

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

不羅嗦了,直接開始擼碼

首先,咱們先寫一個簡單的接口.名字叫AnimalInterface,用來聲明規范動物的一些基本方法.

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

?
1
2
3
4
5
6
7
8
9
10
11
package proxy.imp;
public interface AnimalInterface {
  //設置名字
  void setName(String name);
  //獲取名字
  String getName();
  //叫聲
  void say();
  //獲取棲性
  void getProperty();
}

然后咱們實現這個接口,創建一個名叫小黑的Dog

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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("小狗是陸地動物,但是會游泳哦");
  }
}

大家一定迫不及待了,怎么實現類似AOP的功能呢….

咱們先創建一個名為AOPHandle的類,讓其實現InvocationHandler接口,不能使用invoke時使用proxy作為反射參數時,因為代理對象的接口,不同于對象,這種代理機制是面向接口,而不是面向類的,如果使用proxy,會造成無限遞歸.然后就是棧溢出,但是依舊能反射成功一次,這說明代理對象和對象的代理是不一樣的,但是咱們可以通過proxy參數的proxy.getClass()獲得class對象,然后獲得被代理類的方法和參數,這也為注解注入,特定方法注入,屬性注入提供了一種實現途徑吧,關于這個,咱們后面再說..

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class AOPHandle implements InvocationHandler{
  //保存對象
  private Object o;
  public AOPHandle(Object o) {
    this.o=o;
  }
  /**
   * 這個方法會自動調用,Java動態代理機制
   * 會傳入下面是個參數
   * @param Object proxy 代理對象的接口,不同于對象
   * @param Method method 被調用方法
   * @param Object[] args 方法參數
   * 不能使用invoke時使用proxy作為反射參數時,因為代理對象的接口,不同于對象
   * 這種代理機制是面向接口,而不是面向類的
   **/
  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //方法返回值
    Object ret=null;
    //打印方法名稱
    System.err.println("執行方法:"+method.getName()+"n參數類型為:");
    //打印參數
    for(Class type:method.getParameterTypes())
      System.err.println(type.getName());
    //打印返回類型
    System.err.println("返回數據類型:"+method.getReturnType().getName());
    //反射調用方法
    ret=method.invoke(o, args);
    //聲明結束
    System.err.println("方法執行結束");
    //返回反射調用方法的返回值
    return ret;
  }
}

動態代理已經搞定..然后就是咱們的AnimalFactory了..咱們繼續

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package proxy;
import java.lang.reflect.Proxy;
public class AnimalFactory {
  /***
   * 獲取對象方法
   * @param obj
   * @return
   */
  private static Object getAnimalBase(Object obj){
    //獲取代理對象
    return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
        obj.getClass().getInterfaces(), new AOPHandle(obj));
  }
  /***
   * 獲取對象方法
   * @param obj
   * @return
   */
  @SuppressWarnings("unchecked")
  public static T getAnimal(Object obj){
    return (T) getAnimalBase(obj);
  }
  /***
   * 獲取對象方法
   * @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;
  }
  /***
   * 獲取對象方法
   * @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;
  }
}

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

哈哈…小二,上個菜..哦~不對,是個測試類..哈哈////

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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());
  }
}

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

什么AOP,我怎么一點AOP的影子都沒有看到,怎么切入自定義方法,就一個syso輸入,往這忽悠觀眾來了?…..

好吧,那咱們繼續…看看如何實現注入自定義方法…

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

創建after和before方法,接收Object proxy, Method method, Object[] args參數

這樣就能做更多的事情叻…比如執行方法前,記錄類狀態,寫入log.監控xx變量,,,

開啟你的腦洞吧.

?
1
2
3
4
5
6
7
8
9
package proxy.imp;
import java.lang.reflect.Method;
 
public interface AOPMethod{
  //實例方法執行前執行的方法
  void after(Object proxy, Method method, Object[] args);
  //實例方法執行后執行的方法
  void before(Object proxy, Method method, Object[] args);
}

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

在修改構造方法,讓在類初始化時獲得AOPMethod實例.

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package proxy;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
 
import proxy.imp.AOPMethod;
 
public class AOPHandle implements InvocationHandler{
  //保存對象
  private AOPMethod method;
  private Object o;
  public AOPHandle(Object o,AOPMethod method) {
    this.o=o;
    this.method=method;
  }
  /**
   * 這個方法會自動調用,Java動態代理機制
   * 會傳入下面是個參數
   * @param Object proxy 代理對象的接口,不同于對象
   * @param Method method 被調用方法
   * @param Object[] args 方法參數
   * 不能使用invoke時使用proxy作為反射參數時,因為代理對象的接口,不同于對象
   * 這種代理機制是面向接口,而不是面向類的
   **/
  @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;
  }
}

呼呼,大功告成,,看起來一切都么問題,萌萌噠..

趕緊更新下測試類…

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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() {
      // 這里寫方法執行前的AOP切入方法
      public void before(Object proxy, Method method, Object[] args) {
        System.err.println("我在" + method.getName() + "方法執行前執行");
      }
 
      // 這里系方法執行后的AOP切入方法
      public void after(Object proxy, Method method, Object[] args) {
        System.err.println("我在 " + method.getName() + "方法執行后執行");
 
      }
    });
    dog.say();
    String name1="我的名字是" + dog.getName();
    System.out.println(name1);
    dog.setName("二狗子");
    String name2="我的名字是"+dog.getName();
    System.out.println(name2);
  }
}

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

看起來一切都已經完美了,但是總覺得差了點什么?哦,對,缺少了類似于Spring那么樣的配置文件..

其實那些已經很簡單了,交給你們去做吧,設計好XML格式化就妥了,等等,你說什么,還不能攔截自定義方法?

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

當然,本例的并沒有什么實用意義,更不能個各種完善的AOP框架相比,本文僅僅為您提供一種思路,但是一定要記住,再牛的東西也是一點點積累出來的

實例下載:JavaAOP.rar

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。

原文鏈接:http://blog.csdn.net/seven_73/article/details/53409169

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 天天爱天天做天天爽天天躁 | 午夜在线观看免费观看 视频 | 午夜福利视频极品国产83 | 扒开双腿疯狂进出爽爽动态图 | 臀控福利大臀的网站 | 99青青青精品视频在线 | 日本网络视频www色高清免费 | 日本视频高清 | 日本中文字幕永久在线 | 18free性欧美另类hd | 特黄aa级毛片免费视频播放 | 午夜在线观看免费完整直播网页 | 性欧美xxxxx高清 | 欧美日韩在线观看区一二 | 亚洲国产成人久久综合一区77 | 狠狠色狠狠色综合日日小蛇 | 无限好资源免费观看 | 九九国产在线观看 | 国产免费不卡视频 | 黄a 大片a v 永久免费 | 日韩欧美中文字幕一区 | 无人在线高清观看 | 亚洲免费色 | 欧美日韩国产一区二区三区欧 | 男人都懂www深夜免费网站 | 温柔校草高h | 国产91素人搭讪系列天堂 | 成人久久18免费网站入口 | 国产一二区视频 | 国产成人精品1024在线 | 国内交换一区二区三区 | 亚洲麻豆精品果冻传媒 | 魔兽官方小说 | 强制高h| 香蕉精品国产高清自在自线 | 国产一卡二卡3卡4卡四卡在线 | 草莓在深夜释放自己软件 | 日本ssswww大学生 | 亚洲2023无矿砖码砖区 | 美女视频黄a | 国产高清精品自在久久 |